Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / ui / webui / ntp / recently_closed_tabs_handler.cc
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 #include "chrome/browser/ui/webui/ntp/recently_closed_tabs_handler.h"
6
7 #include "base/bind.h"
8 #include "base/bind_helpers.h"
9 #include "base/metrics/histogram.h"
10 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/sessions/tab_restore_service_delegate.h"
12 #include "chrome/browser/sessions/tab_restore_service_factory.h"
13 #include "chrome/browser/ui/host_desktop.h"
14 #include "chrome/browser/ui/webui/ntp/new_tab_ui.h"
15 #include "chrome/common/url_constants.h"
16 #include "content/public/browser/web_contents.h"
17 #include "content/public/browser/web_ui.h"
18 #include "ui/base/webui/web_ui_util.h"
19
20 namespace {
21
22 void TabToValue(const TabRestoreService::Tab& tab,
23                 base::DictionaryValue* dictionary) {
24   const sessions::SerializedNavigationEntry& current_navigation =
25       tab.navigations.at(tab.current_navigation_index);
26   NewTabUI::SetUrlTitleAndDirection(dictionary, current_navigation.title(),
27                                     current_navigation.virtual_url());
28   dictionary->SetString("type", "tab");
29   dictionary->SetDouble("timestamp", tab.timestamp.ToDoubleT());
30 }
31
32 void WindowToValue(const TabRestoreService::Window& window,
33                    base::DictionaryValue* dictionary) {
34   DCHECK(!window.tabs.empty());
35
36   scoped_ptr<base::ListValue> tab_values(new base::ListValue());
37   for (size_t i = 0; i < window.tabs.size(); ++i) {
38     base::DictionaryValue* tab_value = new base::DictionaryValue();
39     TabToValue(window.tabs[i], tab_value);
40     tab_values->Append(tab_value);
41   }
42
43   dictionary->SetString("type", "window");
44   dictionary->SetDouble("timestamp", window.timestamp.ToDoubleT());
45   dictionary->Set("tabs", tab_values.release());
46 }
47
48 }  // namespace
49
50 void RecentlyClosedTabsHandler::RegisterMessages() {
51   web_ui()->RegisterMessageCallback("getRecentlyClosedTabs",
52       base::Bind(&RecentlyClosedTabsHandler::HandleGetRecentlyClosedTabs,
53                  base::Unretained(this)));
54   web_ui()->RegisterMessageCallback("reopenTab",
55       base::Bind(&RecentlyClosedTabsHandler::HandleReopenTab,
56                  base::Unretained(this)));
57   web_ui()->RegisterMessageCallback("clearRecentlyClosed",
58       base::Bind(&RecentlyClosedTabsHandler::HandleClearRecentlyClosed,
59                  base::Unretained(this)));
60 }
61
62 RecentlyClosedTabsHandler::~RecentlyClosedTabsHandler() {
63   if (tab_restore_service_)
64     tab_restore_service_->RemoveObserver(this);
65 }
66
67 void RecentlyClosedTabsHandler::HandleReopenTab(const base::ListValue* args) {
68   if (!tab_restore_service_)
69     return;
70
71   double session_to_restore = 0.0;
72   CHECK(args->GetDouble(0, &session_to_restore));
73
74   double index = -1.0;
75   CHECK(args->GetDouble(1, &index));
76
77   // There are actually less than 20 restore tab items displayed in the UI.
78   UMA_HISTOGRAM_ENUMERATION("NewTabPage.SessionRestore",
79                             static_cast<int>(index), 20);
80
81   TabRestoreServiceDelegate* delegate =
82       TabRestoreServiceDelegate::FindDelegateForWebContents(
83           web_ui()->GetWebContents());
84   if (!delegate)
85     return;
86   chrome::HostDesktopType host_desktop_type =
87       chrome::GetHostDesktopTypeForNativeView(
88           web_ui()->GetWebContents()->GetNativeView());
89   WindowOpenDisposition disposition = webui::GetDispositionFromClick(args, 2);
90   tab_restore_service_->RestoreEntryById(delegate,
91                                          static_cast<int>(session_to_restore),
92                                          host_desktop_type,
93                                          disposition);
94   // The current tab has been nuked at this point; don't touch any member
95   // variables.
96 }
97
98 void RecentlyClosedTabsHandler::HandleClearRecentlyClosed(
99     const base::ListValue* args) {
100   EnsureTabRestoreService();
101   if (tab_restore_service_)
102     tab_restore_service_->ClearEntries();
103 }
104
105 void RecentlyClosedTabsHandler::HandleGetRecentlyClosedTabs(
106     const base::ListValue* args) {
107   EnsureTabRestoreService();
108   if (tab_restore_service_)
109     TabRestoreServiceChanged(tab_restore_service_);
110 }
111
112 void RecentlyClosedTabsHandler::TabRestoreServiceChanged(
113     TabRestoreService* service) {
114   base::ListValue list_value;
115   const int max_count = 10;
116   int added_count = 0;
117   // We filter the list of recently closed to only show 'interesting' entries,
118   // where an interesting entry is either a closed window or a closed tab
119   // whose selected navigation is not the new tab ui.
120   for (TabRestoreService::Entries::const_iterator it =
121            service->entries().begin();
122        it != service->entries().end() && added_count < max_count; ++it) {
123     TabRestoreService::Entry* entry = *it;
124     scoped_ptr<base::DictionaryValue> entry_dict(new base::DictionaryValue());
125     if (entry->type == TabRestoreService::TAB) {
126       TabToValue(*static_cast<TabRestoreService::Tab*>(entry),
127                  entry_dict.get());
128     } else  {
129       DCHECK_EQ(entry->type, TabRestoreService::WINDOW);
130       WindowToValue(*static_cast<TabRestoreService::Window*>(entry),
131                     entry_dict.get());
132     }
133
134     entry_dict->SetInteger("sessionId", entry->id);
135     list_value.Append(entry_dict.release());
136     ++added_count;
137   }
138
139   web_ui()->CallJavascriptFunction("ntp.setRecentlyClosedTabs", list_value);
140 }
141
142 void RecentlyClosedTabsHandler::TabRestoreServiceDestroyed(
143     TabRestoreService* service) {
144   tab_restore_service_ = NULL;
145 }
146
147 void RecentlyClosedTabsHandler::EnsureTabRestoreService() {
148   if (tab_restore_service_)
149     return;
150
151   tab_restore_service_ =
152       TabRestoreServiceFactory::GetForProfile(Profile::FromWebUI(web_ui()));
153
154   // TabRestoreServiceFactory::GetForProfile() can return NULL (i.e., when in
155   // Off the Record mode)
156   if (tab_restore_service_) {
157     // This does nothing if the tabs have already been loaded or they
158     // shouldn't be loaded.
159     tab_restore_service_->LoadTabsFromLastSession();
160     tab_restore_service_->AddObserver(this);
161   }
162 }