15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/app_list/app_list_view_delegate.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <vector>
868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "apps/custom_launcher_page_contents.h"
10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/callback.h"
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "base/command_line.h"
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/files/file_path.h"
135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/metrics/user_metrics.h"
1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/stl_util.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/apps/scoped_keep_alive.h"
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/browser_process.h"
173551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#include "chrome/browser/chrome_notification_types.h"
1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "chrome/browser/profiles/profile_info_cache.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile_manager.h"
20010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/search/hotword_service.h"
21010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "chrome/browser/search/hotword_service_factory.h"
222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/app_list/app_list_controller_delegate.h"
23f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/app_list/app_list_service.h"
24f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/app_list/app_list_syncable_service.h"
25f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "chrome/browser/ui/app_list/app_list_syncable_service_factory.h"
2690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/browser/ui/app_list/search/search_controller.h"
274e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)#include "chrome/browser/ui/app_list/start_page_service.h"
285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)#include "chrome/browser/ui/apps/chrome_app_delegate.h"
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/browser_finder.h"
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/chrome_pages.h"
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/host_desktop.h"
320f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)#include "chrome/browser/ui/scoped_tabbed_browser_displayer.h"
33eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/web_applications/web_app.h"
34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "chrome/common/chrome_switches.h"
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/common/extensions/extension_constants.h"
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "chrome/common/url_constants.h"
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "components/signin/core/browser/signin_manager.h"
38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "content/public/browser/browser_thread.h"
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/public/browser/notification_service.h"
4090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "content/public/browser/page_navigator.h"
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/user_metrics.h"
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "content/public/browser/web_contents.h"
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/browser/extension_registry.h"
44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "extensions/common/constants.h"
456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "extensions/common/extension_set.h"
466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)#include "extensions/common/manifest_constants.h"
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/common/manifest_handlers/launcher_page_info.h"
485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "grit/theme_resources.h"
49010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/app_list/app_list_switches.h"
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/app_list/app_list_view_delegate_observer.h"
5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "ui/app_list/search_box_model.h"
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "ui/app_list/speech_ui_model.h"
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "ui/base/resource/resource_bundle.h"
54116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "ui/views/controls/webview/webview.h"
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(TOOLKIT_VIEWS)
5746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "ui/views/controls/webview/webview.h"
5846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif
5946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
60010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if defined(USE_AURA)
61010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#include "ui/keyboard/keyboard_util.h"
62010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif
63010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_ASH)
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ash/shell.h"
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "ash/wm/maximize_mode/maximize_mode_controller.h"
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/ash/app_list/app_sync_ui_state_watcher.h"
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
71eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "chrome/browser/web_applications/web_app_win.h"
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
73eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
74010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
75010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)namespace chrome {
76010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)const char kAppLauncherCategoryTag[] = "AppLauncher";
77010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}  // namespace chrome
78010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
79eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochnamespace {
80eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kAutoLaunchDefaultTimeoutMilliSec = 50;
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid CreateShortcutInWebAppDir(
85eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const base::FilePath& app_data_dir,
86eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    base::Callback<void(const base::FilePath&)> callback,
87a02191e04bc25c4935f804f2c080ae28663d096dBen Murdoch    const web_app::ShortcutInfo& info) {
88eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  content::BrowserThread::PostTaskAndReplyWithResult(
89eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      content::BrowserThread::FILE,
90eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      FROM_HERE,
91eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(web_app::CreateShortcutInWebAppDir, app_data_dir, info),
92eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      callback);
93eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
94eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
95eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void PopulateUsers(const ProfileInfoCache& profile_info,
9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                   const base::FilePath& active_profile_path,
98f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)                   app_list::AppListViewDelegate::Users* users) {
99f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  users->clear();
10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  const size_t count = profile_info.GetNumberOfProfiles();
10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (size_t i = 0; i < count; ++i) {
102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    app_list::AppListViewDelegate::User user;
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    user.name = profile_info.GetNameOfProfileAtIndex(i);
10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    user.email = profile_info.GetUserNameOfProfileAtIndex(i);
10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    user.profile_path = profile_info.GetPathOfProfileAtIndex(i);
10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    user.active = active_profile_path == user.profile_path;
10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    users->push_back(user);
10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Gets a list of URLs of the custom launcher pages to show in the launcher.
1126e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// Returns a URL for each installed launcher page. If --custom-launcher-page is
1136e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)// specified and valid, also includes that URL.
1146e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)void GetCustomLauncherPageUrls(content::BrowserContext* browser_context,
1156e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                               std::vector<GURL>* urls) {
1166e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // First, check the command line.
1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
1186e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  if (app_list::switches::IsExperimentalAppListEnabled() &&
1196e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      command_line->HasSwitch(switches::kCustomLauncherPage)) {
1206e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    GURL custom_launcher_page_url(
1216e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        command_line->GetSwitchValueASCII(switches::kCustomLauncherPage));
1226e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    if (custom_launcher_page_url.SchemeIs(extensions::kExtensionScheme)) {
1246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      urls->push_back(custom_launcher_page_url);
1256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    } else {
1266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      LOG(ERROR) << "Invalid custom launcher page URL: "
1276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)                 << custom_launcher_page_url.possibly_invalid_spec();
1286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    }
1296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
1316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  // Search the list of installed extensions for ones with 'launcher_page'.
1326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  extensions::ExtensionRegistry* extension_registry =
1336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      extensions::ExtensionRegistry::Get(browser_context);
1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  const extensions::ExtensionSet& enabled_extensions =
1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      extension_registry->enabled_extensions();
1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for (extensions::ExtensionSet::const_iterator it = enabled_extensions.begin();
1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       it != enabled_extensions.end();
1386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       ++it) {
1396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    const extensions::Extension* extension = it->get();
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    extensions::LauncherPageInfo* info =
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        extensions::LauncherPageHandler::GetInfo(extension);
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (!info)
1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)      continue;
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    urls->push_back(extension->GetResourceURL(info->page));
1466e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
1476e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)}
1486e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
149eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}  // namespace
150eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciAppListViewDelegate::AppListViewDelegate(AppListControllerDelegate* controller)
152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    : controller_(controller),
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      profile_(NULL),
154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      model_(NULL),
155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      scoped_observer_(this) {
1564e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  CHECK(controller_);
157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // The SigninManagerFactor and the SigninManagers are observed to keep the
158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // profile switcher menu up to date, with the correct list of profiles and the
159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // correct email address (or none for signed out users) for each.
160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  SigninManagerFactory::GetInstance()->AddObserver(this);
161a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  // Start observing all already-created SigninManagers.
163a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  ProfileManager* profile_manager = g_browser_process->profile_manager();
164116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  std::vector<Profile*> profiles = profile_manager->GetLoadedProfiles();
165116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  for (std::vector<Profile*>::iterator i = profiles.begin();
166116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       i != profiles.end();
167116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch       ++i) {
168116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    SigninManagerBase* manager =
169116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        SigninManagerFactory::GetForProfileIfExists(*i);
170116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (manager) {
171116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      DCHECK(!scoped_observer_.IsObserving(manager));
172116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      scoped_observer_.Add(manager);
173116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
174116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
175116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
176a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  profile_manager->GetProfileInfoCache().AddObserver(this);
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  speech_ui_.reset(new app_list::SpeechUIModel);
1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if defined(GOOGLE_CHROME_BUILD)
1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  speech_ui_->set_logo(
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      *ui::ResourceBundle::GetSharedInstance().GetImageSkiaNamed(
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          IDR_APP_LIST_GOOGLE_LOGO_VOICE_SEARCH));
1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif
1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  registrar_.Add(this,
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 chrome::NOTIFICATION_APP_TERMINATING,
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 content::NotificationService::AllSources());
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciAppListViewDelegate::~AppListViewDelegate() {
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Note that the destructor is not always called. E.g. on Mac, this is owned
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // by a leaky singleton. Essential shutdown work must be done by observing
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // chrome::NOTIFICATION_APP_TERMINATING.
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetProfile(NULL);
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  g_browser_process->profile_manager()->GetProfileInfoCache().RemoveObserver(
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      this);
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SigninManagerFactory* factory = SigninManagerFactory::GetInstance();
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (factory)
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    factory->RemoveObserver(this);
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AppListViewDelegate::SetProfile(Profile* new_profile) {
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (profile_ == new_profile)
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (profile_) {
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Note: |search_controller_| has a reference to |speech_ui_| so must be
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // destroyed first.
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    search_controller_.reset();
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    custom_page_contents_.clear();
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    app_list::StartPageService* start_page_service =
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        app_list::StartPageService::Get(profile_);
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    if (start_page_service)
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      start_page_service->RemoveObserver(this);
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(USE_ASH)
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    app_sync_ui_state_watcher_.reset();
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    model_ = NULL;
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  profile_ = new_profile;
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!profile_) {
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    speech_ui_->SetSpeechRecognitionState(app_list::SPEECH_RECOGNITION_OFF);
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  model_ =
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      app_list::AppListSyncableServiceFactory::GetForProfile(profile_)->model();
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(USE_ASH)
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  app_sync_ui_state_watcher_.reset(new AppSyncUIStateWatcher(profile_, model_));
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetUpSearchUI();
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetUpProfileSwitcher();
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetUpCustomLauncherPages();
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Clear search query.
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  model_->search_box()->SetText(base::string16());
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AppListViewDelegate::SetUpSearchUI() {
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  app_list::StartPageService* start_page_service =
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      app_list::StartPageService::Get(profile_);
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (start_page_service)
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    start_page_service->AddObserver(this);
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  speech_ui_->SetSpeechRecognitionState(start_page_service
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                            ? start_page_service->state()
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                            : app_list::SPEECH_RECOGNITION_OFF);
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  search_controller_.reset(new app_list::SearchController(profile_,
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                          model_->search_box(),
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                          model_->results(),
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                          speech_ui_.get(),
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                          controller_));
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AppListViewDelegate::SetUpProfileSwitcher() {
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // If a profile change is observed when there is no app list, there is nothing
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // to update until SetProfile() calls this function again.
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!profile_)
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
265116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Don't populate the app list users if we are on the ash desktop.
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow(
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      controller_->GetAppListWindow());
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (desktop == chrome::HOST_DESKTOP_TYPE_ASH)
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Populate the app list users.
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  PopulateUsers(g_browser_process->profile_manager()->GetProfileInfoCache(),
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                profile_->GetPath(),
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                &users_);
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  FOR_EACH_OBSERVER(
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      app_list::AppListViewDelegateObserver, observers_, OnProfilesChanged());
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AppListViewDelegate::SetUpCustomLauncherPages() {
2826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::vector<GURL> custom_launcher_page_urls;
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  GetCustomLauncherPageUrls(profile_, &custom_launcher_page_urls);
2846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for (std::vector<GURL>::const_iterator it = custom_launcher_page_urls.begin();
2856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       it != custom_launcher_page_urls.end();
2866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       ++it) {
2876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    std::string extension_id = it->host();
2886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    apps::CustomLauncherPageContents* page_contents =
2896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        new apps::CustomLauncherPageContents(
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            scoped_ptr<extensions::AppDelegate>(
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                new ChromeAppDelegate(scoped_ptr<ScopedKeepAlive>())),
29203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)            extension_id);
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    page_contents->Initialize(profile_, *it);
2946e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    custom_page_contents_.push_back(page_contents);
295116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
29668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
29768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
298010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void AppListViewDelegate::OnHotwordStateChanged(bool started) {
299010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (started) {
300010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (speech_ui_->state() == app_list::SPEECH_RECOGNITION_READY) {
301010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      OnSpeechRecognitionStateChanged(
302010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING);
303010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
304010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  } else {
305010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (speech_ui_->state() == app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING)
306010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      OnSpeechRecognitionStateChanged(app_list::SPEECH_RECOGNITION_READY);
307010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
308010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
309010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
310010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)void AppListViewDelegate::OnHotwordRecognized() {
311010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  DCHECK_EQ(app_list::SPEECH_RECOGNITION_HOTWORD_LISTENING,
312010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)            speech_ui_->state());
313010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  ToggleSpeechRecognition();
314010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
315010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
316116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid AppListViewDelegate::SigninManagerCreated(SigninManagerBase* manager) {
317116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  scoped_observer_.Add(manager);
318116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
319116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
320116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid AppListViewDelegate::SigninManagerShutdown(SigninManagerBase* manager) {
321116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  if (scoped_observer_.IsObserving(manager))
322116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    scoped_observer_.Remove(manager);
323116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
324116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
325116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid AppListViewDelegate::GoogleSigninFailed(
326116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const GoogleServiceAuthError& error) {
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetUpProfileSwitcher();
328116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
329116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AppListViewDelegate::GoogleSigninSucceeded(const std::string& account_id,
3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                                const std::string& username,
332116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                                const std::string& password) {
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetUpProfileSwitcher();
334116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
335116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AppListViewDelegate::GoogleSignedOut(const std::string& account_id,
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                          const std::string& username) {
3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetUpProfileSwitcher();
339116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
340116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AppListViewDelegate::OnProfileAdded(const base::FilePath& profile_path) {
3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetUpProfileSwitcher();
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AppListViewDelegate::OnProfileWasRemoved(
3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::FilePath& profile_path,
3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::string16& profile_name) {
3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetUpProfileSwitcher();
3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
350a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AppListViewDelegate::OnProfileNameChanged(
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::FilePath& profile_path,
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const base::string16& old_profile_name) {
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetUpProfileSwitcher();
355f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
356f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
357f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)bool AppListViewDelegate::ForceNativeDesktop() const {
358f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return controller_->ForceNativeDesktop();
3593551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)}
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
36168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void AppListViewDelegate::SetProfileByPath(const base::FilePath& profile_path) {
36268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  DCHECK(model_);
36368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // The profile must be loaded before this is called.
3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  SetProfile(
3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      g_browser_process->profile_manager()->GetProfileByPath(profile_path));
36668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
36768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
368f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)app_list::AppListModel* AppListViewDelegate::GetModel() {
369f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return model_;
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
372a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)app_list::SpeechUIModel* AppListViewDelegate::GetSpeechUI() {
3735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return speech_ui_.get();
374a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
375a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
376eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochvoid AppListViewDelegate::GetShortcutPathForApp(
377eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const std::string& app_id,
378eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    const base::Callback<void(const base::FilePath&)>& callback) {
379eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#if defined(OS_WIN)
380eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  const extensions::Extension* extension =
381116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      extensions::ExtensionRegistry::Get(profile_)->GetExtensionById(
382116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          app_id, extensions::ExtensionRegistry::EVERYTHING);
383eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  if (!extension) {
384eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    callback.Run(base::FilePath());
385eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    return;
386eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  }
387eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
388eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  base::FilePath app_data_dir(
389eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      web_app::GetWebAppDataDirectory(profile_->GetPath(),
390eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                      extension->id(),
391eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch                                      GURL()));
392eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
393116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  web_app::GetShortcutInfoForApp(
394effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch      extension,
395eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      profile_,
396eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch      base::Bind(CreateShortcutInWebAppDir, app_data_dir, callback));
397eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#else
398eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  callback.Run(base::FilePath());
399eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#endif
400eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
401eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListViewDelegate::StartSearch() {
4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (search_controller_)
40490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    search_controller_->Start();
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListViewDelegate::StopSearch() {
4083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)  if (search_controller_)
40990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    search_controller_->Stop();
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListViewDelegate::OpenSearchResult(
41390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    app_list::SearchResult* result,
4145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    bool auto_launch,
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int event_flags) {
4165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (auto_launch)
4175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::RecordAction(base::UserMetricsAction("AppList_AutoLaunched"));
41890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  search_controller_->OpenResult(result, event_flags);
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListViewDelegate::InvokeSearchResultAction(
42290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    app_list::SearchResult* result,
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int action_index,
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int event_flags) {
42590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  search_controller_->InvokeResultAction(result, action_index, event_flags);
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)base::TimeDelta AppListViewDelegate::GetAutoLaunchTimeout() {
4295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return auto_launch_timeout_;
4305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppListViewDelegate::AutoLaunchCanceled() {
4335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  base::RecordAction(base::UserMetricsAction("AppList_AutoLaunchCanceled"));
4345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  auto_launch_timeout_ = base::TimeDelta();
4355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void AppListViewDelegate::ViewInitialized() {
438c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  app_list::StartPageService* service =
439c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      app_list::StartPageService::Get(profile_);
440010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (service) {
441c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    service->AppListShown();
442010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (service->HotwordEnabled()) {
443010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      HotwordService* hotword_service =
444010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          HotwordServiceFactory::GetForProfile(profile_);
445010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      if (hotword_service)
446010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        hotword_service->RequestHotwordSession(this);
447010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
448010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
4495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
4505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListViewDelegate::Dismiss()  {
4522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  controller_->DismissView();
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppListViewDelegate::ViewClosing() {
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  controller_->ViewClosing();
4575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!profile_)
4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
4601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
461c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch  app_list::StartPageService* service =
462c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      app_list::StartPageService::Get(profile_);
463010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (service) {
464c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    service->AppListHidden();
465010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    if (service->HotwordEnabled()) {
466010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      HotwordService* hotword_service =
467010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)          HotwordServiceFactory::GetForProfile(profile_);
468010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      if (hotword_service)
469010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        hotword_service->StopHotwordSession(this);
470010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    }
471010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  }
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)gfx::ImageSkia AppListViewDelegate::GetWindowIcon() {
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return controller_->GetWindowIcon();
4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListViewDelegate::OpenSettings() {
479116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  const extensions::Extension* extension =
480116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      extensions::ExtensionRegistry::Get(profile_)->GetExtensionById(
481116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          extension_misc::kSettingsAppId,
482116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch          extensions::ExtensionRegistry::EVERYTHING);
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(extension);
48468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  controller_->ActivateApp(profile_,
48568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                           extension,
48668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                           AppListControllerDelegate::LAUNCH_FROM_UNKNOWN,
48768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)                           0);
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
49090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void AppListViewDelegate::OpenHelp() {
49190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow(
49290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      controller_->GetAppListWindow());
4930f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  chrome::ScopedTabbedBrowserDisplayer displayer(profile_, desktop);
4940f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  content::OpenURLParams params(GURL(chrome::kAppLauncherHelpURL),
4950f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                content::Referrer(),
4960f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                NEW_FOREGROUND_TAB,
4971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                ui::PAGE_TRANSITION_LINK,
4980f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                                false);
4990f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  displayer.browser()->OpenURL(params);
50090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)}
50190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)
5022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AppListViewDelegate::OpenFeedback() {
5032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  chrome::HostDesktopType desktop = chrome::GetHostDesktopTypeForNativeWindow(
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      controller_->GetAppListWindow());
5051e9bf3e0803691d0a228da41fc608347b6db4340Torne (Richard Coles)  Browser* browser = chrome::FindTabbedBrowser(profile_, false, desktop);
506c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  chrome::ShowFeedbackPage(browser, std::string(),
507c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                           chrome::kAppLauncherCategoryTag);
5082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)
510f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)void AppListViewDelegate::ToggleSpeechRecognition() {
511f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  app_list::StartPageService* service =
512f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)      app_list::StartPageService::Get(profile_);
513f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  if (service)
514f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    service->ToggleSpeechRecognition();
515f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
516f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
51768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void AppListViewDelegate::ShowForProfileByPath(
51868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    const base::FilePath& profile_path) {
51968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  controller_->ShowForProfileByPath(profile_path);
52068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
52168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
522a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void AppListViewDelegate::OnSpeechResult(const base::string16& result,
523a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                                         bool is_final) {
5245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  speech_ui_->SetSpeechResult(result, is_final);
5255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  if (is_final) {
5265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    auto_launch_timeout_ = base::TimeDelta::FromMilliseconds(
5275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        kAutoLaunchDefaultTimeoutMilliSec);
528a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    model_->search_box()->SetText(result);
5295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  }
530a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
531a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
532a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void AppListViewDelegate::OnSpeechSoundLevelChanged(int16 level) {
5335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  speech_ui_->UpdateSoundLevel(level);
534f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
535f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
536a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void AppListViewDelegate::OnSpeechRecognitionStateChanged(
537a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    app_list::SpeechRecognitionState new_state) {
5385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  speech_ui_->SetSpeechRecognitionState(new_state);
53903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
54003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  app_list::StartPageService* service =
54103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      app_list::StartPageService::Get(profile_);
54203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // With the new hotword extension, we need to re-request hotwording after
54303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // speech recognition has stopped.
54403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (new_state == app_list::SPEECH_RECOGNITION_READY &&
54503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      HotwordService::IsExperimentalHotwordingEnabled() &&
54603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      service && service->HotwordEnabled()) {
54703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    HotwordService* hotword_service =
54803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        HotwordServiceFactory::GetForProfile(profile_);
54903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (hotword_service) {
55003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      hotword_service->RequestHotwordSession(this);
55103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
55203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
553f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
554f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
55546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#if defined(TOOLKIT_VIEWS)
55646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)views::View* AppListViewDelegate::CreateStartPageWebView(
55746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    const gfx::Size& size) {
5584e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  app_list::StartPageService* service =
5594e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)      app_list::StartPageService::Get(profile_);
5604e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)  if (!service)
5614e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)    return NULL;
5624e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)
56346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  content::WebContents* web_contents = service->GetStartPageContents();
56446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  if (!web_contents)
56546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    return NULL;
56646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)
567116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  DCHECK_EQ(profile_, web_contents->GetBrowserContext());
56846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  views::WebView* web_view = new views::WebView(
56946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      web_contents->GetBrowserContext());
57046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  web_view->SetPreferredSize(size);
57146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  web_view->SetWebContents(web_contents);
57246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return web_view;
5735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
574116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5756e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)std::vector<views::View*> AppListViewDelegate::CreateCustomPageWebViews(
576116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    const gfx::Size& size) {
5776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  std::vector<views::View*> web_views;
5786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)
5796e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  for (ScopedVector<apps::CustomLauncherPageContents>::const_iterator it =
5806e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)           custom_page_contents_.begin();
5816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       it != custom_page_contents_.end();
5826e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)       ++it) {
5836e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    content::WebContents* web_contents = (*it)->web_contents();
5846e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // TODO(mgiuca): DCHECK_EQ(profile_, web_contents->GetBrowserContext())
5856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    // after http://crbug.com/392763 resolved.
5866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    views::WebView* web_view =
5876e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)        new views::WebView(web_contents->GetBrowserContext());
5886e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    web_view->SetPreferredSize(size);
5896e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    web_view->SetWebContents(web_contents);
5906e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)    web_views.push_back(web_view);
5916e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  }
592116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
5936e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  return web_views;
594116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
59546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#endif
5965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
59746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)bool AppListViewDelegate::IsSpeechRecognitionEnabled() {
5985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  app_list::StartPageService* service =
5995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      app_list::StartPageService::Get(profile_);
60046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)  return service && service->GetSpeechRecognitionContents();
6014e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)}
602f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)
603f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)const app_list::AppListViewDelegate::Users&
604f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)AppListViewDelegate::GetUsers() const {
605f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  return users_;
606f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)}
607a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
608010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)bool AppListViewDelegate::ShouldCenterWindow() const {
609010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (app_list::switches::IsCenteredAppListEnabled())
610010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return true;
611010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
612010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // keyboard depends upon Aura.
613010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#if defined(USE_AURA)
614010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // If the virtual keyboard is enabled, use the new app list position. The old
615010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  // position is too tall, and doesn't fit in the left-over screen space.
616010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  if (keyboard::IsKeyboardEnabled())
617010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)    return true;
618010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)#endif
619010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
620cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#if defined(USE_ASH)
621cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // If it is at all possible to enter maximize mode in this configuration
622cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // (which has a virtual keyboard), we should use the experimental position.
623cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // This avoids having the app list change shape and position as the user
624cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  // enters and exits maximize mode.
625cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  if (ash::Shell::HasInstance() &&
626cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      ash::Shell::GetInstance()
627cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          ->maximize_mode_controller()
628cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)          ->CanEnterMaximizeMode()) {
629cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;
630cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  }
631cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#endif
632cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
633010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)  return false;
634010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)}
635010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)
636a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void AppListViewDelegate::AddObserver(
637a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    app_list::AppListViewDelegateObserver* observer) {
638a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  observers_.AddObserver(observer);
639a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
640a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
641a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void AppListViewDelegate::RemoveObserver(
642a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    app_list::AppListViewDelegateObserver* observer) {
643a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  observers_.RemoveObserver(observer);
644a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
6451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AppListViewDelegate::Observe(int type,
6471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  const content::NotificationSource& source,
6481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                  const content::NotificationDetails& details) {
6491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  switch (type) {
6501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    case chrome::NOTIFICATION_APP_TERMINATING:
6511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      FOR_EACH_OBSERVER(
6521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          app_list::AppListViewDelegateObserver, observers_, OnShutdown());
6531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SetProfile(NULL);  // Ensures launcher page web contents are torn down.
6551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // SigninManagerFactory is not a leaky singleton (unlike this class), and
6571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      // its destructor will check that it has no remaining observers.
6581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      scoped_observer_.RemoveAll();
6591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SigninManagerFactory::GetInstance()->RemoveObserver(this);
6601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      break;
6611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    default:
6621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      NOTREACHED();
6631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
6641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
665