1// Copyright (c) 2012 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#ifndef CHROME_BROWSER_UI_WEBUI_NTP_NEW_TAB_UI_H_
6#define CHROME_BROWSER_UI_WEBUI_NTP_NEW_TAB_UI_H_
7
8#include <string>
9
10#include "base/gtest_prod_util.h"
11#include "base/prefs/pref_change_registrar.h"
12#include "base/time/time.h"
13#include "base/timer/timer.h"
14#include "content/public/browser/notification_observer.h"
15#include "content/public/browser/notification_registrar.h"
16#include "content/public/browser/url_data_source.h"
17#include "content/public/browser/web_contents.h"
18#include "content/public/browser/web_contents_observer.h"
19#include "content/public/browser/web_ui_controller.h"
20
21class GURL;
22class Profile;
23
24namespace base {
25class DictionaryValue;
26}
27
28namespace user_prefs {
29class PrefRegistrySyncable;
30}
31
32// The WebUIController used for the New Tab page.
33class NewTabUI : public content::WebUIController,
34                 public content::WebContentsObserver,
35                 public content::NotificationObserver {
36 public:
37  explicit NewTabUI(content::WebUI* web_ui);
38  virtual ~NewTabUI();
39
40  static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
41
42  // Returns whether or not to show apps pages.
43  static bool ShouldShowApps();
44
45  // Returns whether or not "Discovery" in the NTP is Enabled.
46  static bool IsDiscoveryInNTPEnabled();
47
48  // Adds "url", "title", and "direction" keys on incoming dictionary, setting
49  // title as the url as a fallback on empty title.
50  static void SetUrlTitleAndDirection(base::DictionaryValue* dictionary,
51                                      const base::string16& title,
52                                      const GURL& gurl);
53
54  // Adds "full_name" and "full_name_direction" keys on incoming dictionary.
55  static void SetFullNameAndDirection(const base::string16& full_name,
56                                      base::DictionaryValue* dictionary);
57
58  // Returns a pointer to a NewTabUI if the WebUIController object is a new tab
59  // page.
60  static NewTabUI* FromWebUIController(content::WebUIController* ui);
61
62  // The current preference version.
63  static int current_pref_version() { return current_pref_version_; }
64
65  // WebUIController implementation:
66  virtual void RenderViewCreated(
67      content::RenderViewHost* render_view_host) OVERRIDE;
68  virtual void RenderViewReused(
69      content::RenderViewHost* render_view_host) OVERRIDE;
70
71  // WebContentsObserver implementation:
72  virtual void WasHidden() OVERRIDE;
73
74  bool showing_sync_bubble() { return showing_sync_bubble_; }
75  void set_showing_sync_bubble(bool showing) { showing_sync_bubble_ = showing; }
76
77  class NewTabHTMLSource : public content::URLDataSource {
78   public:
79    explicit NewTabHTMLSource(Profile* profile);
80    virtual ~NewTabHTMLSource();
81
82    // content::URLDataSource implementation.
83    virtual std::string GetSource() const OVERRIDE;
84    virtual void StartDataRequest(
85        const std::string& path,
86        int render_process_id,
87        int render_frame_id,
88        const content::URLDataSource::GotDataCallback& callback) OVERRIDE;
89    virtual std::string GetMimeType(const std::string&) const OVERRIDE;
90    virtual bool ShouldReplaceExistingSource() const OVERRIDE;
91    virtual bool ShouldAddContentSecurityPolicy() const OVERRIDE;
92
93    // Adds |resource| to the source. |resource_id| is resource id or 0,
94    // which means return empty data set. |mime_type| is mime type of the
95    // resource.
96    void AddResource(const char* resource,
97                     const char* mime_type,
98                     int resource_id);
99
100   private:
101    // Pointer back to the original profile.
102    Profile* profile_;
103
104    // Maps resource files to mime types an resource ids.
105    std::map<std::string, std::pair<std::string, int> > resource_map_;
106
107    DISALLOW_COPY_AND_ASSIGN(NewTabHTMLSource);
108  };
109
110 private:
111  FRIEND_TEST_ALL_PREFIXES(NewTabUITest, UpdateUserPrefsVersion);
112
113  // content::NotificationObserver implementation.
114  virtual void Observe(int type,
115                       const content::NotificationSource& source,
116                       const content::NotificationDetails& details) OVERRIDE;
117
118  // If |web_contents| has an NTP URL, emits a number of NTP statistics (like
119  // mouseovers counts) associated with |web_contents|, to be logged in UMA
120  // histograms.
121  void EmitNtpStatistics();
122
123  void OnShowBookmarkBarChanged();
124
125  void StartTimingPaint(content::RenderViewHost* render_view_host);
126  void PaintTimeout();
127
128  Profile* GetProfile() const;
129
130  content::NotificationRegistrar registrar_;
131
132  // The time when we started benchmarking.
133  base::TimeTicks start_;
134  // The last time we got a paint notification.
135  base::TimeTicks last_paint_;
136  // Scoping so we can be sure our timeouts don't outlive us.
137  base::OneShotTimer<NewTabUI> timer_;
138  // The preference version. This used for migrating prefs of the NTP.
139  static const int current_pref_version_ = 3;
140
141  // If the sync promo NTP bubble is being shown.
142  bool showing_sync_bubble_;
143
144  PrefChangeRegistrar pref_change_registrar_;
145
146  DISALLOW_COPY_AND_ASSIGN(NewTabUI);
147};
148
149#endif  // CHROME_BROWSER_UI_WEBUI_NTP_NEW_TAB_UI_H_
150