OLD | NEW |
| (Empty) |
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/extensions/api/session_restore/session_restore_api.h" | |
6 | |
7 #include <vector> | |
8 | |
9 #include "base/i18n/rtl.h" | |
10 #include "base/lazy_instance.h" | |
11 #include "base/strings/string_number_conversions.h" | |
12 #include "base/strings/utf_string_conversions.h" | |
13 #include "chrome/browser/extensions/extension_function_registry.h" | |
14 #include "chrome/browser/extensions/extension_tab_util.h" | |
15 #include "chrome/browser/profiles/profile.h" | |
16 #include "chrome/browser/sessions/session_restore.h" | |
17 #include "chrome/browser/sessions/tab_restore_service_delegate.h" | |
18 #include "chrome/browser/sessions/tab_restore_service_factory.h" | |
19 #include "chrome/browser/sync/glue/session_model_associator.h" | |
20 #include "chrome/browser/sync/glue/synced_session.h" | |
21 #include "chrome/browser/sync/profile_sync_service.h" | |
22 #include "chrome/browser/sync/profile_sync_service_factory.h" | |
23 #include "chrome/browser/ui/browser.h" | |
24 #include "chrome/browser/ui/browser_finder.h" | |
25 #include "chrome/browser/ui/host_desktop.h" | |
26 #include "chrome/browser/ui/tabs/tab_strip_model.h" | |
27 #include "content/public/browser/web_contents.h" | |
28 #include "ui/base/layout.h" | |
29 | |
30 | |
31 namespace { | |
32 | |
33 const unsigned int kMaxRecentlyClosedSessionResults = 25; | |
34 const char kRecentlyClosedListEmpty[] = | |
35 "There are no recently closed sessions."; | |
36 const char kInvalidSessionId[] = "Invalid session id."; | |
37 const char kNoBrowserToRestoreSession[] = | |
38 "There are no browser windows to restore the session."; | |
39 | |
40 } // namespace | |
41 | |
42 namespace extensions { | |
43 | |
44 namespace GetRecentlyClosed = api::session_restore::GetRecentlyClosed; | |
45 namespace Restore = api::session_restore::Restore; | |
46 namespace tabs = api::tabs; | |
47 namespace windows = api::windows; | |
48 namespace session_restore = api::session_restore; | |
49 | |
50 scoped_ptr<tabs::Tab> SessionRestoreGetRecentlyClosedFunction::CreateTabModel( | |
51 const TabRestoreService::Tab& tab, int selected_index) { | |
52 scoped_ptr<tabs::Tab> tab_struct(new tabs::Tab); | |
53 const sessions::SerializedNavigationEntry& current_navigation = | |
54 tab.navigations[tab.current_navigation_index]; | |
55 GURL gurl = current_navigation.virtual_url(); | |
56 std::string title = UTF16ToUTF8(current_navigation.title()); | |
57 | |
58 tab_struct->url.reset(new std::string(gurl.spec())); | |
59 tab_struct->title.reset(new std::string(title.empty() ? gurl.spec() : title)); | |
60 tab_struct->index = tab.tabstrip_index; | |
61 tab_struct->pinned = tab.pinned; | |
62 tab_struct->id = tab.id; | |
63 tab_struct->window_id = tab.browser_id; | |
64 tab_struct->index = tab.tabstrip_index; | |
65 tab_struct->pinned = tab.pinned; | |
66 tab_struct->selected = tab.tabstrip_index == selected_index; | |
67 tab_struct->active = false; | |
68 tab_struct->highlighted = false; | |
69 tab_struct->incognito = false; | |
70 ExtensionTabUtil::ScrubTabForExtension(GetExtension(), | |
71 tab_struct.get()); | |
72 return tab_struct.Pass(); | |
73 } | |
74 | |
75 scoped_ptr<windows::Window> | |
76 SessionRestoreGetRecentlyClosedFunction::CreateWindowModel( | |
77 const TabRestoreService::Window& window) { | |
78 scoped_ptr<windows::Window> window_struct(new windows::Window); | |
79 DCHECK(!window.tabs.empty()); | |
80 | |
81 scoped_ptr<std::vector<linked_ptr<tabs::Tab> > > tabs( | |
82 new std::vector<linked_ptr<tabs::Tab> >); | |
83 for (size_t i = 0; i < window.tabs.size(); ++i) { | |
84 tabs->push_back(make_linked_ptr(CreateTabModel(window.tabs[i], | |
85 window.selected_tab_index).release())); | |
86 } | |
87 window_struct->tabs.reset(tabs.release()); | |
88 window_struct->incognito = false; | |
89 window_struct->always_on_top = false; | |
90 window_struct->focused = false; | |
91 window_struct->type = windows::Window::TYPE_NORMAL; | |
92 window_struct->state = windows::Window::STATE_NORMAL; | |
93 return window_struct.Pass(); | |
94 } | |
95 | |
96 scoped_ptr<session_restore::ClosedEntry> | |
97 SessionRestoreGetRecentlyClosedFunction::CreateEntryModel( | |
98 const TabRestoreService::Entry* entry) { | |
99 scoped_ptr<session_restore::ClosedEntry> entry_struct( | |
100 new session_restore::ClosedEntry); | |
101 switch (entry->type) { | |
102 case TabRestoreService::TAB: | |
103 entry_struct->tab.reset(CreateTabModel( | |
104 *static_cast<const TabRestoreService::Tab*>(entry), -1).release()); | |
105 break; | |
106 case TabRestoreService::WINDOW: | |
107 entry_struct->window.reset(CreateWindowModel( | |
108 *static_cast<const TabRestoreService::Window*>(entry)).release()); | |
109 break; | |
110 default: | |
111 NOTREACHED(); | |
112 } | |
113 entry_struct->timestamp = entry->timestamp.ToTimeT(); | |
114 entry_struct->id = entry->id; | |
115 return entry_struct.Pass(); | |
116 } | |
117 | |
118 bool SessionRestoreGetRecentlyClosedFunction::RunImpl() { | |
119 scoped_ptr<GetRecentlyClosed::Params> params( | |
120 GetRecentlyClosed::Params::Create(*args_)); | |
121 EXTENSION_FUNCTION_VALIDATE(params.get()); | |
122 unsigned int max_results = kMaxRecentlyClosedSessionResults; | |
123 if (params->options && params->options->max_results) | |
124 max_results = *params->options->max_results; | |
125 EXTENSION_FUNCTION_VALIDATE(max_results >= 0 && | |
126 max_results <= kMaxRecentlyClosedSessionResults); | |
127 | |
128 std::vector<linked_ptr<session_restore::ClosedEntry> > result; | |
129 TabRestoreService* tab_restore_service = | |
130 TabRestoreServiceFactory::GetForProfile(profile()); | |
131 DCHECK(tab_restore_service); | |
132 | |
133 // List of entries. They are ordered from most to least recent. | |
134 // We prune the list to contain max 25 entries at any time and removes | |
135 // uninteresting entries. | |
136 TabRestoreService::Entries entries = tab_restore_service->entries(); | |
137 for (TabRestoreService::Entries::const_iterator it = entries.begin(); | |
138 it != entries.end() && result.size() < max_results; ++it) { | |
139 TabRestoreService::Entry* entry = *it; | |
140 if (!params->options || params->options->entry_type == | |
141 GetRecentlyClosed::Params::Options::ENTRY_TYPE_NONE) { | |
142 // Include both tabs and windows if type is not defined. | |
143 result.push_back(make_linked_ptr(CreateEntryModel(entry).release())); | |
144 } else if ( | |
145 (params->options->entry_type == | |
146 GetRecentlyClosed::Params::Options::ENTRY_TYPE_TAB && | |
147 entry->type == TabRestoreService::TAB) || | |
148 (params->options->entry_type == | |
149 GetRecentlyClosed::Params::Options::ENTRY_TYPE_WINDOW && | |
150 entry->type == TabRestoreService::WINDOW)) { | |
151 result.push_back(make_linked_ptr(CreateEntryModel(entry).release())); | |
152 } | |
153 } | |
154 | |
155 results_ = GetRecentlyClosed::Results::Create(result); | |
156 return true; | |
157 } | |
158 | |
159 bool SessionRestoreRestoreFunction::RunImpl() { | |
160 scoped_ptr<Restore::Params> params(Restore::Params::Create(*args_)); | |
161 EXTENSION_FUNCTION_VALIDATE(params.get()); | |
162 | |
163 Browser* browser = | |
164 chrome::FindBrowserWithProfile(profile(), | |
165 chrome::HOST_DESKTOP_TYPE_NATIVE); | |
166 if (!browser) { | |
167 error_ = kNoBrowserToRestoreSession; | |
168 return false; | |
169 } | |
170 | |
171 TabRestoreService* tab_restore_service = | |
172 TabRestoreServiceFactory::GetForProfile(profile()); | |
173 TabRestoreServiceDelegate* delegate = | |
174 TabRestoreServiceDelegate::FindDelegateForWebContents( | |
175 browser->tab_strip_model()->GetActiveWebContents()); | |
176 DCHECK(delegate); | |
177 chrome::HostDesktopType host_desktop_type = browser->host_desktop_type(); | |
178 TabRestoreService::Entries entries = tab_restore_service->entries(); | |
179 | |
180 if (entries.empty()) { | |
181 error_ = kRecentlyClosedListEmpty; | |
182 return false; | |
183 } | |
184 | |
185 if (!params->id) { | |
186 tab_restore_service->RestoreMostRecentEntry(delegate, host_desktop_type); | |
187 return true; | |
188 } | |
189 | |
190 // Check if the recently closed list contains an entry with the provided id. | |
191 bool is_valid_id = false; | |
192 for (TabRestoreService::Entries::iterator it = entries.begin(); | |
193 it != entries.end(); ++it) { | |
194 if ((*it)->id == *params->id) { | |
195 is_valid_id = true; | |
196 break; | |
197 } | |
198 | |
199 // For Window entries, see if the ID matches a tab. If so, report true for | |
200 // the window as the Entry. | |
201 if ((*it)->type == TabRestoreService::WINDOW) { | |
202 std::vector<TabRestoreService::Tab>& tabs = | |
203 static_cast<TabRestoreService::Window*>(*it)->tabs; | |
204 for (std::vector<TabRestoreService::Tab>::iterator tab_it = tabs.begin(); | |
205 tab_it != tabs.end(); ++tab_it) { | |
206 if ((*tab_it).id == *params->id) { | |
207 is_valid_id = true; | |
208 break; | |
209 } | |
210 } | |
211 } | |
212 } | |
213 | |
214 if (!is_valid_id) { | |
215 error_ = kInvalidSessionId; | |
216 return false; | |
217 } | |
218 | |
219 tab_restore_service->RestoreEntryById(delegate, *params->id, | |
220 host_desktop_type, UNKNOWN); | |
221 return true; | |
222 } | |
223 | |
224 SessionRestoreAPI::SessionRestoreAPI(Profile* profile) { | |
225 } | |
226 | |
227 SessionRestoreAPI::~SessionRestoreAPI() { | |
228 } | |
229 | |
230 static base::LazyInstance<ProfileKeyedAPIFactory<SessionRestoreAPI> > | |
231 g_factory = LAZY_INSTANCE_INITIALIZER; | |
232 | |
233 // static | |
234 ProfileKeyedAPIFactory<SessionRestoreAPI>* | |
235 SessionRestoreAPI::GetFactoryInstance() { | |
236 return &g_factory.Get(); | |
237 } | |
238 | |
239 } // namespace extensions | |
OLD | NEW |