start_page_service.cc revision f2477e01787aa58f445919b809d89e252beef54f
1// Copyright 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/app_list/start_page_service.h"
6
7#include <string>
8
9#include "base/command_line.h"
10#include "base/memory/singleton.h"
11#include "chrome/browser/chrome_notification_types.h"
12#include "chrome/browser/extensions/extension_system_factory.h"
13#include "chrome/browser/extensions/install_tracker_factory.h"
14#include "chrome/browser/media/media_stream_infobar_delegate.h"
15#include "chrome/browser/profiles/profile.h"
16#include "chrome/browser/ui/app_list/recommended_apps.h"
17#include "chrome/browser/ui/app_list/start_page_observer.h"
18#include "chrome/common/chrome_switches.h"
19#include "chrome/common/url_constants.h"
20#include "components/browser_context_keyed_service/browser_context_dependency_manager.h"
21#include "components/browser_context_keyed_service/browser_context_keyed_service_factory.h"
22#include "content/public/browser/notification_details.h"
23#include "content/public/browser/notification_observer.h"
24#include "content/public/browser/notification_registrar.h"
25#include "content/public/browser/notification_service.h"
26#include "content/public/browser/notification_source.h"
27#include "content/public/browser/web_contents.h"
28#include "content/public/browser/web_contents_delegate.h"
29#include "extensions/common/extension.h"
30
31namespace app_list {
32
33class StartPageService::Factory : public BrowserContextKeyedServiceFactory {
34 public:
35  static StartPageService* GetForProfile(Profile* profile) {
36    if (!CommandLine::ForCurrentProcess()->HasSwitch(
37            switches::kShowAppListStartPage)) {
38      return NULL;
39    }
40
41    return static_cast<StartPageService*>(
42        GetInstance()->GetServiceForBrowserContext(profile, true));
43  }
44
45  static Factory* GetInstance() {
46    return Singleton<Factory>::get();
47  }
48
49 private:
50  friend struct DefaultSingletonTraits<Factory>;
51
52  Factory()
53      : BrowserContextKeyedServiceFactory(
54            "AppListStartPageService",
55            BrowserContextDependencyManager::GetInstance()) {
56    DependsOn(extensions::ExtensionSystemFactory::GetInstance());
57    DependsOn(extensions::InstallTrackerFactory::GetInstance());
58  }
59
60  virtual ~Factory() {}
61
62  // BrowserContextKeyedServiceFactory overrides:
63  virtual BrowserContextKeyedService* BuildServiceInstanceFor(
64      content::BrowserContext* context) const OVERRIDE {
65     Profile* profile = static_cast<Profile*>(context);
66     return new StartPageService(profile);
67  }
68
69  DISALLOW_COPY_AND_ASSIGN(Factory);
70};
71
72class StartPageService::ProfileDestroyObserver
73    : public content::NotificationObserver {
74 public:
75  explicit ProfileDestroyObserver(StartPageService* service)
76      : service_(service) {
77    registrar_.Add(this,
78                   chrome::NOTIFICATION_PROFILE_DESTROYED,
79                   content::Source<Profile>(service_->profile()));
80  }
81  virtual ~ProfileDestroyObserver() {}
82
83 private:
84  // content::NotificationObserver
85  virtual void Observe(int type,
86                       const content::NotificationSource& source,
87                       const content::NotificationDetails& details) OVERRIDE {
88    DCHECK_EQ(chrome::NOTIFICATION_PROFILE_DESTROYED, type);
89    DCHECK_EQ(service_->profile(), content::Details<Profile>(details).ptr());
90    service_->Shutdown();
91  }
92
93  StartPageService* service_;  // Owner of this class.
94  content::NotificationRegistrar registrar_;
95
96  DISALLOW_COPY_AND_ASSIGN(ProfileDestroyObserver);
97};
98
99class StartPageService::StartPageWebContentsDelegate
100    : public content::WebContentsDelegate {
101 public:
102  StartPageWebContentsDelegate() {}
103  virtual ~StartPageWebContentsDelegate() {}
104
105  virtual void RequestMediaAccessPermission(
106      content::WebContents* web_contents,
107      const content::MediaStreamRequest& request,
108      const content::MediaResponseCallback& callback) OVERRIDE {
109    if (MediaStreamInfoBarDelegate::Create(web_contents, request, callback))
110      NOTREACHED() << "Media stream not allowed for WebUI";
111  }
112
113 private:
114  DISALLOW_COPY_AND_ASSIGN(StartPageWebContentsDelegate);
115};
116
117// static
118StartPageService* StartPageService::Get(Profile* profile) {
119  return Factory::GetForProfile(profile);
120}
121
122StartPageService::StartPageService(Profile* profile)
123    : profile_(profile),
124      profile_destroy_observer_(new ProfileDestroyObserver(this)),
125      recommended_apps_(new RecommendedApps(profile)) {
126  contents_.reset(content::WebContents::Create(
127      content::WebContents::CreateParams(profile_)));
128  contents_delegate_.reset(new StartPageWebContentsDelegate());
129  contents_->SetDelegate(contents_delegate_.get());
130
131  GURL url(chrome::kChromeUIAppListStartPageURL);
132  CommandLine* command_line = CommandLine::ForCurrentProcess();
133  if (command_line->HasSwitch(switches::kAppListStartPageURL)) {
134    url = GURL(
135        command_line->GetSwitchValueASCII(switches::kAppListStartPageURL));
136  }
137
138  contents_->GetController().LoadURL(
139      url,
140      content::Referrer(),
141      content::PAGE_TRANSITION_AUTO_TOPLEVEL,
142      std::string());
143}
144
145StartPageService::~StartPageService() {}
146
147void StartPageService::AddObserver(StartPageObserver* observer) {
148  observers_.AddObserver(observer);
149}
150
151void StartPageService::RemoveObserver(StartPageObserver* observer) {
152  observers_.RemoveObserver(observer);
153}
154
155void StartPageService::ToggleSpeechRecognition() {
156  contents_->GetWebUI()->CallJavascriptFunction(
157      "appList.startPage.toggleSpeechRecognition");
158}
159
160void StartPageService::OnSearch(const base::string16& query) {
161  FOR_EACH_OBSERVER(StartPageObserver, observers_, OnSearch(query));
162}
163
164void StartPageService::OnSpeechRecognitionStateChanged(bool recognizing) {
165  FOR_EACH_OBSERVER(StartPageObserver,
166                    observers_,
167                    OnSpeechRecognitionStateChanged(recognizing));
168}
169
170void StartPageService::Shutdown() {
171  contents_.reset();
172}
173
174}  // namespace app_list
175