Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: chrome/browser/extensions/api/sessions/sessions_api.cc

Issue 21022018: Sessions API - previously Session Restore API. Supports restoring currently open foreign windows an… (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/session_restore/session_restore_api.h" 5 #include "chrome/browser/extensions/api/sessions/sessions_api.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/i18n/rtl.h" 9 #include "base/i18n/rtl.h"
10 #include "base/lazy_instance.h" 10 #include "base/lazy_instance.h"
11 #include "base/prefs/pref_service.h"
11 #include "base/strings/string_number_conversions.h" 12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h" 14 #include "base/strings/utf_string_conversions.h"
15 #include "base/time/time.h"
16 #include "chrome/browser/extensions/api/sessions/session_id.h"
17 #include "chrome/browser/extensions/api/tabs/windows_util.h"
18 #include "chrome/browser/extensions/extension_function_dispatcher.h"
13 #include "chrome/browser/extensions/extension_function_registry.h" 19 #include "chrome/browser/extensions/extension_function_registry.h"
14 #include "chrome/browser/extensions/extension_tab_util.h" 20 #include "chrome/browser/extensions/extension_tab_util.h"
21 #include "chrome/browser/extensions/window_controller.h"
22 #include "chrome/browser/extensions/window_controller_list.h"
15 #include "chrome/browser/profiles/profile.h" 23 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/sessions/session_restore.h" 24 #include "chrome/browser/sessions/session_restore.h"
17 #include "chrome/browser/sessions/tab_restore_service_delegate.h" 25 #include "chrome/browser/sessions/tab_restore_service_delegate.h"
18 #include "chrome/browser/sessions/tab_restore_service_factory.h" 26 #include "chrome/browser/sessions/tab_restore_service_factory.h"
19 #include "chrome/browser/sync/glue/session_model_associator.h" 27 #include "chrome/browser/sync/glue/session_model_associator.h"
20 #include "chrome/browser/sync/glue/synced_session.h" 28 #include "chrome/browser/sync/glue/synced_session.h"
21 #include "chrome/browser/sync/profile_sync_service.h" 29 #include "chrome/browser/sync/profile_sync_service.h"
22 #include "chrome/browser/sync/profile_sync_service_factory.h" 30 #include "chrome/browser/sync/profile_sync_service_factory.h"
23 #include "chrome/browser/ui/browser.h" 31 #include "chrome/browser/ui/browser.h"
24 #include "chrome/browser/ui/browser_finder.h" 32 #include "chrome/browser/ui/browser_finder.h"
25 #include "chrome/browser/ui/host_desktop.h" 33 #include "chrome/browser/ui/host_desktop.h"
26 #include "chrome/browser/ui/tabs/tab_strip_model.h" 34 #include "chrome/browser/ui/tabs/tab_strip_model.h"
35 #include "chrome/common/pref_names.cc"
27 #include "content/public/browser/web_contents.h" 36 #include "content/public/browser/web_contents.h"
37 #include "extensions/common/error_utils.h"
38 #include "net/base/net_util.h"
28 #include "ui/base/layout.h" 39 #include "ui/base/layout.h"
29 40
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 { 41 namespace extensions {
43 42
44 namespace GetRecentlyClosed = api::session_restore::GetRecentlyClosed; 43 namespace GetRecentlyClosed = api::sessions::GetRecentlyClosed;
45 namespace Restore = api::session_restore::Restore; 44 namespace GetDevices = api::sessions::GetDevices;
45 namespace Restore = api::sessions::Restore;
46 namespace tabs = api::tabs; 46 namespace tabs = api::tabs;
47 namespace windows = api::windows; 47 namespace windows = api::windows;
48 namespace session_restore = api::session_restore;
49 48
50 scoped_ptr<tabs::Tab> SessionRestoreGetRecentlyClosedFunction::CreateTabModel( 49 const int kMaxRecentlyClosedSessionResults = 25;
not at google - send to devlin 2013/08/19 19:34:40 I just remembered something else. You can define c
51 const TabRestoreService::Tab& tab, int selected_index) { 50 const int kMaxDeviceResults = 10;
not at google - send to devlin 2013/08/15 20:16:24 See comment in last patchset; I don't think having
Kristen Dwan 2013/08/16 22:03:06 Done.
51 const char kNoRecentlyClosedSessionsError[] =
52 "There are no recently closed sessions.";
53 const char kInvalidSessionIdError[] = "Invalid session id: \"*\".";
54 const char kNoBrowserToRestoreSession[] =
55 "There are no browser windows to restore the session.";
56 const char kSessionSyncError[] = "Synced sessions are not available.";
57
58 // Comparator function for use with std::sort that will sort sessions by
59 // descending modified_time (i.e., most recent first).
60 bool SortSessionsByRecency(const browser_sync::SyncedSession* s1,
61 const browser_sync::SyncedSession* s2) {
62 return s1->modified_time > s2->modified_time;
63 }
64
65 scoped_ptr<tabs::Tab> CreateTabModelHelper(
66 Profile* profile,
67 const sessions::SerializedNavigationEntry& current_navigation,
68 const std::string& session_id,
69 int index,
70 bool pinned,
71 int selected_index,
72 const Extension* extension) {
52 scoped_ptr<tabs::Tab> tab_struct(new tabs::Tab); 73 scoped_ptr<tabs::Tab> tab_struct(new tabs::Tab);
53 const sessions::SerializedNavigationEntry& current_navigation = 74
54 tab.navigations[tab.current_navigation_index];
55 GURL gurl = current_navigation.virtual_url(); 75 GURL gurl = current_navigation.virtual_url();
56 std::string title = UTF16ToUTF8(current_navigation.title()); 76 std::string title = UTF16ToUTF8(current_navigation.title());
57 77
78 tab_struct->session_id.reset(new std::string(session_id));
58 tab_struct->url.reset(new std::string(gurl.spec())); 79 tab_struct->url.reset(new std::string(gurl.spec()));
59 tab_struct->title.reset(new std::string(title.empty() ? gurl.spec() : title)); 80 if (!title.empty()) {
60 tab_struct->index = tab.tabstrip_index; 81 tab_struct->title.reset(new std::string(title));
61 tab_struct->pinned = tab.pinned; 82 } else {
62 tab_struct->id = tab.id; 83 const std::string languages(
not at google - send to devlin 2013/08/15 20:16:24 general nit: prefer assign syntax = over construct
Kristen Dwan 2013/08/16 22:03:06 Done.
63 tab_struct->window_id = tab.browser_id; 84 profile->GetPrefs()->GetString(prefs::kAcceptLanguages));
64 tab_struct->index = tab.tabstrip_index; 85 tab_struct->title.reset(new std::string(UTF16ToUTF8(
65 tab_struct->pinned = tab.pinned; 86 net::FormatUrl(gurl, languages, net::kFormatUrlOmitAll,
66 tab_struct->selected = tab.tabstrip_index == selected_index; 87 net::UnescapeRule::NORMAL, NULL, NULL, NULL))));
not at google - send to devlin 2013/08/15 20:16:24 I think you only need the first 2 arguments.
Kristen Dwan 2013/08/16 22:03:06 Done.
88 }
89 tab_struct->index = index;
90 tab_struct->pinned = pinned;
91 tab_struct->selected = index == selected_index;
67 tab_struct->active = false; 92 tab_struct->active = false;
68 tab_struct->highlighted = false; 93 tab_struct->highlighted = false;
69 tab_struct->incognito = false; 94 tab_struct->incognito = false;
70 ExtensionTabUtil::ScrubTabForExtension(GetExtension(), 95 ExtensionTabUtil::ScrubTabForExtension(extension, tab_struct.get());
71 tab_struct.get());
72 return tab_struct.Pass(); 96 return tab_struct.Pass();
73 } 97 }
74 98
99 scoped_ptr<windows::Window> CreateWindowModelHelper(
100 scoped_ptr<std::vector<linked_ptr<tabs::Tab> > > tabs,
101 const std::string& session_id,
102 const windows::Window::Type& type,
103 const windows::Window::State& state) {
104 scoped_ptr<windows::Window> window_struct(new windows::Window);
105 window_struct->tabs.reset(tabs.release());
not at google - send to devlin 2013/08/15 20:16:24 should be able to do window_struct->tabs = tabs.Pa
Kristen Dwan 2013/08/16 22:03:06 Done.
106 window_struct->session_id.reset(new std::string(session_id));
107 window_struct->incognito = false;
108 window_struct->always_on_top = false;
109 window_struct->focused = false;
110 window_struct->type = type;
111 window_struct->state = state;
112 return window_struct.Pass();
113 }
114
115 scoped_ptr<api::sessions::Session> CreateSessionModelHelper(
116 int last_modified,
117 scoped_ptr<tabs::Tab> tab,
118 scoped_ptr<windows::Window> window) {
119 scoped_ptr<api::sessions::Session> session_struct(new api::sessions::Session);
120 session_struct->last_modified = last_modified;
121 if (tab)
122 session_struct->tab.reset(tab.release());
123 else if (window)
124 session_struct->window.reset(window.release());
125 else
126 NOTREACHED();
127 return session_struct.Pass();
128 }
129
130 bool is_tab_entry(const TabRestoreService::Entry* entry) {
131 return entry->type == TabRestoreService::TAB;
132 }
133
134 bool is_window_entry(const TabRestoreService::Entry* entry) {
135 return entry->type == TabRestoreService::WINDOW;
136 }
137
138 scoped_ptr<tabs::Tab> SessionsGetRecentlyClosedFunction::CreateTabModel(
139 const TabRestoreService::Tab& tab, int session_id, int selected_index) {
140 return CreateTabModelHelper(profile(),
141 tab.navigations[tab.current_navigation_index],
142 base::IntToString(session_id),
143 tab.tabstrip_index,
144 tab.pinned,
145 selected_index,
146 GetExtension());
147 }
148
75 scoped_ptr<windows::Window> 149 scoped_ptr<windows::Window>
76 SessionRestoreGetRecentlyClosedFunction::CreateWindowModel( 150 SessionsGetRecentlyClosedFunction::CreateWindowModel(
77 const TabRestoreService::Window& window) { 151 const TabRestoreService::Window& window,
78 scoped_ptr<windows::Window> window_struct(new windows::Window); 152 int session_id) {
79 DCHECK(!window.tabs.empty()); 153 DCHECK(!window.tabs.empty());
80 154
81 scoped_ptr<std::vector<linked_ptr<tabs::Tab> > > tabs( 155 scoped_ptr<std::vector<linked_ptr<tabs::Tab> > > tabs(
82 new std::vector<linked_ptr<tabs::Tab> >); 156 new std::vector<linked_ptr<tabs::Tab> >);
83 for (size_t i = 0; i < window.tabs.size(); ++i) { 157 for (size_t i = 0; i < window.tabs.size(); ++i) {
84 tabs->push_back(make_linked_ptr(CreateTabModel(window.tabs[i], 158 tabs->push_back(make_linked_ptr(
85 window.selected_tab_index).release())); 159 CreateTabModel(window.tabs[i], window.tabs[i].id,
160 window.selected_tab_index).release()));
86 } 161 }
87 window_struct->tabs.reset(tabs.release()); 162
88 window_struct->incognito = false; 163 return CreateWindowModelHelper(tabs.Pass(),
89 window_struct->always_on_top = false; 164 base::IntToString(session_id),
90 window_struct->focused = false; 165 windows::Window::TYPE_NORMAL,
91 window_struct->type = windows::Window::TYPE_NORMAL; 166 windows::Window::STATE_NORMAL);
92 window_struct->state = windows::Window::STATE_NORMAL;
93 return window_struct.Pass();
94 } 167 }
95 168
96 scoped_ptr<session_restore::ClosedEntry> 169 scoped_ptr<api::sessions::Session>
97 SessionRestoreGetRecentlyClosedFunction::CreateEntryModel( 170 SessionsGetRecentlyClosedFunction::CreateSessionModel(
98 const TabRestoreService::Entry* entry) { 171 const TabRestoreService::Entry* entry) {
99 scoped_ptr<session_restore::ClosedEntry> entry_struct( 172 scoped_ptr<tabs::Tab> tab;
100 new session_restore::ClosedEntry); 173 scoped_ptr<windows::Window> window;
101 switch (entry->type) { 174 switch (entry->type) {
102 case TabRestoreService::TAB: 175 case TabRestoreService::TAB:
103 entry_struct->tab.reset(CreateTabModel( 176 tab = CreateTabModel(
104 *static_cast<const TabRestoreService::Tab*>(entry), -1).release()); 177 *static_cast<const TabRestoreService::Tab*>(entry), entry->id, -1);
105 break; 178 break;
106 case TabRestoreService::WINDOW: 179 case TabRestoreService::WINDOW:
107 entry_struct->window.reset(CreateWindowModel( 180 window = CreateWindowModel(
108 *static_cast<const TabRestoreService::Window*>(entry)).release()); 181 *static_cast<const TabRestoreService::Window*>(entry), entry->id);
109 break; 182 break;
110 default: 183 default:
111 NOTREACHED(); 184 NOTREACHED();
112 } 185 }
113 entry_struct->timestamp = entry->timestamp.ToTimeT(); 186 return CreateSessionModelHelper(entry->timestamp.ToTimeT(),
114 entry_struct->id = entry->id; 187 tab.Pass(),
115 return entry_struct.Pass(); 188 window.Pass());
116 } 189 }
117 190
118 bool SessionRestoreGetRecentlyClosedFunction::RunImpl() { 191 bool SessionsGetRecentlyClosedFunction::RunImpl() {
119 scoped_ptr<GetRecentlyClosed::Params> params( 192 scoped_ptr<GetRecentlyClosed::Params> params(
120 GetRecentlyClosed::Params::Create(*args_)); 193 GetRecentlyClosed::Params::Create(*args_));
121 EXTENSION_FUNCTION_VALIDATE(params.get()); 194 EXTENSION_FUNCTION_VALIDATE(params.get());
122 unsigned int max_results = kMaxRecentlyClosedSessionResults; 195 int max_results = kMaxRecentlyClosedSessionResults;
123 if (params->options && params->options->max_results) 196 if (params->options && params->options->max_results)
124 max_results = *params->options->max_results; 197 max_results = *params->options->max_results;
125 EXTENSION_FUNCTION_VALIDATE(max_results >= 0 && 198 EXTENSION_FUNCTION_VALIDATE(max_results >= 0 &&
126 max_results <= kMaxRecentlyClosedSessionResults); 199 max_results <= kMaxRecentlyClosedSessionResults);
127 200
128 std::vector<linked_ptr<session_restore::ClosedEntry> > result; 201 std::vector<linked_ptr<api::sessions::Session> > result;
129 TabRestoreService* tab_restore_service = 202 TabRestoreService* tab_restore_service =
130 TabRestoreServiceFactory::GetForProfile(profile()); 203 TabRestoreServiceFactory::GetForProfile(profile());
131 DCHECK(tab_restore_service); 204 DCHECK(tab_restore_service);
132 205
133 // List of entries. They are ordered from most to least recent. 206 // 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 207 // We prune the list to contain max 25 entries at any time and removes
135 // uninteresting entries. 208 // uninteresting entries.
136 TabRestoreService::Entries entries = tab_restore_service->entries(); 209 TabRestoreService::Entries entries = tab_restore_service->entries();
137 for (TabRestoreService::Entries::const_iterator it = entries.begin(); 210 for (TabRestoreService::Entries::const_iterator it = entries.begin();
138 it != entries.end() && result.size() < max_results; ++it) { 211 it != entries.end() && static_cast<int>(result.size()) < max_results;
212 ++it) {
139 TabRestoreService::Entry* entry = *it; 213 TabRestoreService::Entry* entry = *it;
140 if (!params->options || params->options->entry_type == 214 if (!params->options || params->options->entry_type ==
141 GetRecentlyClosed::Params::Options::ENTRY_TYPE_NONE) { 215 GetRecentlyClosed::Params::Options::ENTRY_TYPE_NONE) {
142 // Include both tabs and windows if type is not defined. 216 // Include both tabs and windows if type is not defined.
143 result.push_back(make_linked_ptr(CreateEntryModel(entry).release())); 217 result.push_back(make_linked_ptr(CreateSessionModel(entry).release()));
144 } else if ( 218 } else if (
145 (params->options->entry_type == 219 (params->options->entry_type ==
146 GetRecentlyClosed::Params::Options::ENTRY_TYPE_TAB && 220 GetRecentlyClosed::Params::Options::ENTRY_TYPE_TAB &&
147 entry->type == TabRestoreService::TAB) || 221 is_tab_entry(entry)) ||
148 (params->options->entry_type == 222 (params->options->entry_type ==
149 GetRecentlyClosed::Params::Options::ENTRY_TYPE_WINDOW && 223 GetRecentlyClosed::Params::Options::ENTRY_TYPE_WINDOW &&
150 entry->type == TabRestoreService::WINDOW)) { 224 is_window_entry(entry))) {
151 result.push_back(make_linked_ptr(CreateEntryModel(entry).release())); 225 result.push_back(make_linked_ptr(CreateSessionModel(entry).release()));
152 } 226 }
153 } 227 }
154 228
155 results_ = GetRecentlyClosed::Results::Create(result); 229 results_ = GetRecentlyClosed::Results::Create(result);
156 return true; 230 return true;
157 } 231 }
158 232
159 bool SessionRestoreRestoreFunction::RunImpl() { 233 scoped_ptr<tabs::Tab> SessionsGetDevicesFunction::CreateTabModel(
234 const std::string& session_tag,
235 const SessionTab& tab,
236 int tab_index,
237 int selected_index) {
238 std::string session_id = SessionId(session_tag, tab.tab_id.id()).ToString();
239 return CreateTabModelHelper(profile(),
240 tab.navigations[tab.current_navigation_index],
241 session_id,
242 tab_index,
243 tab.pinned,
244 selected_index,
245 GetExtension());
246 }
247
248 scoped_ptr<windows::Window> SessionsGetDevicesFunction::CreateWindowModel(
249 const SessionWindow& window, const std::string& session_tag) {
250 DCHECK(!window.tabs.empty());
251
252 scoped_ptr<std::vector<linked_ptr<tabs::Tab> > > tabs(
253 new std::vector<linked_ptr<tabs::Tab> >);
254 for (size_t i = 0; i < window.tabs.size(); ++i) {
255 tabs->push_back(make_linked_ptr(
256 CreateTabModel(session_tag, *window.tabs[i], i,
257 window.selected_tab_index).release()));
258 }
259
260 std::string session_id =
261 SessionId(session_tag, window.window_id.id()).ToString();
262
263 windows::Window::Type type = windows::Window::TYPE_NONE;
264 switch (window.type) {
265 case Browser::TYPE_TABBED:
266 type = windows::Window::TYPE_NORMAL;
267 break;
268 case Browser::TYPE_POPUP:
269 type = windows::Window::TYPE_POPUP;
270 break;
271 }
272
273 windows::Window::State state = windows::Window::STATE_NONE;
274 switch (window.show_state) {
275 case ui::SHOW_STATE_NORMAL:
276 state = windows::Window::STATE_NORMAL;
277 break;
278 case ui::SHOW_STATE_MINIMIZED:
279 state = windows::Window::STATE_MINIMIZED;
280 break;
281 case ui::SHOW_STATE_MAXIMIZED:
282 state = windows::Window::STATE_MAXIMIZED;
283 break;
284 case ui::SHOW_STATE_FULLSCREEN:
285 state = windows::Window::STATE_FULLSCREEN;
286 break;
287 default:
288 break;
not at google - send to devlin 2013/08/15 20:16:24 but no need for the default: case.
Kristen Dwan 2013/08/16 22:03:06 there are 4 cases not dealt with here that we just
not at google - send to devlin 2013/08/19 19:34:40 That's ok, just be explicit about those 4 argument
Kristen Dwan 2013/08/19 21:35:05 Done.
289 }
290
291 scoped_ptr<windows::Window> window_struct(
292 CreateWindowModelHelper(tabs.Pass(), session_id, type, state));
293 // TODO(dwankri): Dig deeper to resolve bounds not being optional, so closed
294 // windows in GetRecentlyClosed can have set values in Window helper.
295 window_struct->left.reset(new int(window.bounds.x()));
296 window_struct->top.reset(new int(window.bounds.y()));
297 window_struct->width.reset(new int(window.bounds.width()));
298 window_struct->height.reset(new int(window.bounds.height()));
299
300 return window_struct.Pass();
301 }
302
303 scoped_ptr<api::sessions::Session>
304 SessionsGetDevicesFunction::CreateSessionModel(
305 const SessionWindow& window, const std::string& session_tag) {
306 return CreateSessionModelHelper(window.timestamp.ToTimeT(),
307 scoped_ptr<tabs::Tab>(),
308 CreateWindowModel(window, session_tag));
309 }
310
311 scoped_ptr<api::sessions::Device> SessionsGetDevicesFunction::CreateDeviceModel(
312 const browser_sync::SyncedSession* session) {
313 scoped_ptr<api::sessions::Device> device_struct(new api::sessions::Device);
314 device_struct->info = session->session_name;
315
316 for (browser_sync::SyncedSession::SyncedWindowMap::const_iterator it =
317 session->windows.begin(); it != session->windows.end(); ++it) {
318 device_struct->sessions.push_back(make_linked_ptr(CreateSessionModel(
319 *it->second, session->session_tag).release()));
320 }
321 return device_struct.Pass();
322 }
323
324 bool SessionsGetDevicesFunction::RunImpl() {
325 ProfileSyncService* service =
326 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile());
327 if (!(service && service->GetPreferredDataTypes().Has(syncer::SESSIONS))) {
328 // Sync not enabled.
329 results_ = GetDevices::Results::Create(
330 std::vector<linked_ptr<api::sessions::Device> >());
331 return true;
332 }
333
334 browser_sync::SessionModelAssociator* associator =
335 service->GetSessionModelAssociator();
336 std::vector<const browser_sync::SyncedSession*> sessions;
337 if (!(associator && associator->GetAllForeignSessions(&sessions))) {
338 results_ = GetDevices::Results::Create(
339 std::vector<linked_ptr<api::sessions::Device> >());
340 return true;
341 }
342
343 int max_results = kMaxDeviceResults;
344 scoped_ptr<GetDevices::Params> params(GetDevices::Params::Create(*args_));
345 EXTENSION_FUNCTION_VALIDATE(params.get());
346 if (params->options && params->options->max_results)
347 max_results = *params->options->max_results.get();
348 EXTENSION_FUNCTION_VALIDATE(max_results >= 0 &&
349 max_results <= kMaxDeviceResults);
350
351 std::vector<linked_ptr<api::sessions::Device> > result;
352 // Sort sessions from most recent to least recent.
353 std::sort(sessions.begin(), sessions.end(), SortSessionsByRecency);
354 for (size_t i = 0; i < sessions.size() &&
355 static_cast<int>(result.size()) < max_results; ++i) {
356 result.push_back(make_linked_ptr(CreateDeviceModel(sessions[i]).release()));
357 }
358
359 results_ = GetDevices::Results::Create(result);
360 return true;
361 }
362
363 void SessionsRestoreFunction::SetInvalidIdError(const std::string& invalid_id) {
364 SetError(ErrorUtils::FormatErrorMessage(kInvalidSessionIdError, invalid_id));
365 }
366
367
368 void SessionsRestoreFunction::SetResultRestoredTab(
369 const content::WebContents* contents) {
370 scoped_ptr<tabs::Tab> tab(tabs::Tab::FromValue(
371 *ExtensionTabUtil::CreateTabValue(contents, GetExtension())));
372 results_ = Restore::Results::Create(*CreateSessionModelHelper(
not at google - send to devlin 2013/08/15 20:16:24 I think this is dereferencing a just-released poin
Kristen Dwan 2013/08/16 22:03:06 Done.
373 base::Time::Now().ToTimeT(),
374 tab.Pass(),
375 scoped_ptr<windows::Window>()).release());
376 }
377
378 bool SessionsRestoreFunction::SetResultRestoredWindow(int window_id) {
379 WindowController* controller = NULL;
380 if (!windows_util::GetWindowFromWindowID(this, window_id, &controller)) {
381 // error_ is set by GetWindowFromWindowId function call.
382 return false;
383 }
384 scoped_ptr<windows::Window> window(windows::Window::FromValue(
385 *controller->CreateWindowValueWithTabs(GetExtension())));
386 results_ = Restore::Results::Create(*CreateSessionModelHelper(
387 base::Time::Now().ToTimeT(),
388 scoped_ptr<tabs::Tab>(),
389 window.Pass()).get());
390 return true;
391 }
392
393 bool SessionsRestoreFunction::RestoreMostRecentlyClosed(Browser* browser) {
394 TabRestoreService* tab_restore_service =
395 TabRestoreServiceFactory::GetForProfile(profile());
396 chrome::HostDesktopType host_desktop_type = browser->host_desktop_type();
397 TabRestoreService::Entries entries = tab_restore_service->entries();
398
399 if (entries.empty()) {
400 SetError(kNoRecentlyClosedSessionsError);
401 return false;
402 }
403
404 bool is_window = is_window_entry(entries.front());
405 TabRestoreServiceDelegate* delegate =
406 TabRestoreServiceDelegate::FindDelegateForWebContents(
407 browser->tab_strip_model()->GetActiveWebContents());
408 std::vector<content::WebContents*> contents =
409 tab_restore_service->RestoreMostRecentEntry(delegate, host_desktop_type);
410 DCHECK(contents.size());
411
412 if (is_window) {
413 return SetResultRestoredWindow(
414 ExtensionTabUtil::GetWindowIdOfTab(contents[0]));
415 }
416
417 SetResultRestoredTab(contents[0]);
418 return true;
419 }
420
421 bool SessionsRestoreFunction::RestoreLocalSession(const SessionId* session_id,
not at google - send to devlin 2013/08/15 20:16:24 just pass in a const ref
Kristen Dwan 2013/08/16 22:03:06 Done.
422 Browser* browser) {
423 TabRestoreService* tab_restore_service =
424 TabRestoreServiceFactory::GetForProfile(profile());
425 chrome::HostDesktopType host_desktop_type = browser->host_desktop_type();
426 TabRestoreService::Entries entries = tab_restore_service->entries();
427
428 if (entries.empty()) {
429 SetInvalidIdError(session_id->ToString());
430 return false;
431 }
432
433 // Check if the recently closed list contains an entry with the provided id.
434 bool is_window = false;
435 for (TabRestoreService::Entries::iterator it = entries.begin();
436 it != entries.end(); ++it) {
437 if ((*it)->id == session_id->id()) {
438 // The only time a full window is being restored is if the entry ID
439 // matches the provided ID and the entry type is Window.
440 is_window = is_window_entry(*it);
441 break;
442 }
443 }
444
445 TabRestoreServiceDelegate* delegate =
446 TabRestoreServiceDelegate::FindDelegateForWebContents(
447 browser->tab_strip_model()->GetActiveWebContents());
448 std::vector<content::WebContents*> contents =
449 tab_restore_service->RestoreEntryById(delegate,
450 session_id->id(),
451 host_desktop_type,
452 UNKNOWN);
453 // If the ID is invalid, contents will be empty.
454 if (!contents.size()) {
455 SetInvalidIdError(session_id->ToString());
456 return false;
457 }
458
459 // Retrieve the window through any of the tabs in contents.
460 if (is_window) {
461 return SetResultRestoredWindow(
462 ExtensionTabUtil::GetWindowIdOfTab(contents[0]));
463 }
464
465 SetResultRestoredTab(contents[0]);
466 return true;
467 }
468
469 bool SessionsRestoreFunction::RestoreForeignSession(const SessionId* session_id,
not at google - send to devlin 2013/08/15 20:16:24 const ref
Kristen Dwan 2013/08/16 22:03:06 Done.
470 Browser* browser) {
471 ProfileSyncService* service =
472 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile());
473 if (!(service && service->GetPreferredDataTypes().Has(syncer::SESSIONS))) {
474 SetError(kSessionSyncError);
475 return false;
476 }
477 browser_sync::SessionModelAssociator* associator =
478 service->GetSessionModelAssociator();
479 if (!associator) {
480 SetError(kSessionSyncError);
481 return false;
482 }
483
484 const SessionTab* tab = NULL;
485 if (associator->GetForeignTab(session_id->session_tag(),
486 session_id->id(),
487 &tab)) {
488 TabStripModel* tab_strip = browser->tab_strip_model();
489 content::WebContents* contents = tab_strip->GetActiveWebContents();
490
491 content::WebContents* tab_contents =
492 SessionRestore::RestoreForeignSessionTab(contents, *tab,
493 NEW_FOREGROUND_TAB);
494 SetResultRestoredTab(tab_contents);
495 return true;
496 }
497
498 // Restoring a full window.
499 std::vector<const SessionWindow*> windows;
500 if (!associator->GetForeignSession(session_id->session_tag(), &windows)) {
501 SetInvalidIdError(session_id->ToString());
502 return false;
503 }
504
505 std::vector<const SessionWindow*>::const_iterator window = windows.begin();
506 while (window != windows.end()
507 && (*window)->window_id.id() != session_id->id()) {
not at google - send to devlin 2013/08/15 20:16:24 nitty align condition vertically
Kristen Dwan 2013/08/16 22:03:06 Done.
508 ++window;
509 }
510 if (window == windows.end()) {
511 SetInvalidIdError(session_id->ToString());
512 return false;
513 }
514
515 chrome::HostDesktopType host_desktop_type = browser->host_desktop_type();
516 // Only restore one window at a time.
517 std::vector<Browser*> browsers =
518 SessionRestore::RestoreForeignSessionWindows(profile(), host_desktop_type,
519 window, window + 1);
520 // Will always create one browser because we only restore one window per call.
521 DCHECK_EQ(1u, browsers.size());
522 return SetResultRestoredWindow(ExtensionTabUtil::GetWindowId(browsers[0]));
523 }
524
525 bool SessionsRestoreFunction::RunImpl() {
160 scoped_ptr<Restore::Params> params(Restore::Params::Create(*args_)); 526 scoped_ptr<Restore::Params> params(Restore::Params::Create(*args_));
161 EXTENSION_FUNCTION_VALIDATE(params.get()); 527 EXTENSION_FUNCTION_VALIDATE(params.get());
162 528
163 Browser* browser = 529 Browser* browser =
164 chrome::FindBrowserWithProfile(profile(), 530 chrome::FindBrowserWithProfile(profile(),
165 chrome::HOST_DESKTOP_TYPE_NATIVE); 531 chrome::HOST_DESKTOP_TYPE_NATIVE);
166 if (!browser) { 532 if (!browser) {
167 error_ = kNoBrowserToRestoreSession; 533 SetError(kNoBrowserToRestoreSession);
168 return false; 534 return false;
169 } 535 }
170 536
171 TabRestoreService* tab_restore_service = 537 if (!params->session_id)
172 TabRestoreServiceFactory::GetForProfile(profile()); 538 return RestoreMostRecentlyClosed(browser);
173 TabRestoreServiceDelegate* delegate = 539
174 TabRestoreServiceDelegate::FindDelegateForWebContents( 540 scoped_ptr<SessionId> session_id(SessionId::Parse(*params->session_id));
175 browser->tab_strip_model()->GetActiveWebContents()); 541 if (!session_id) {
176 DCHECK(delegate); 542 SetInvalidIdError(*params->session_id);
177 chrome::HostDesktopType host_desktop_type = browser->host_desktop_type(); 543 return false;
178 TabRestoreService::Entries entries = tab_restore_service->entries(); 544 }
179 545
180 if (entries.empty()) { 546 if (session_id->IsForeign()) {
181 error_ = kRecentlyClosedListEmpty; 547 return RestoreForeignSession(session_id.get(), browser);
182 return false; 548 }
183 } 549 return RestoreLocalSession(session_id.get(), browser);
not at google - send to devlin 2013/08/15 20:16:24 ternary if you feel like it
Kristen Dwan 2013/08/16 22:03:06 Done.
184 550 }
185 if (!params->id) { 551
186 tab_restore_service->RestoreMostRecentEntry(delegate, host_desktop_type); 552 SessionsAPI::SessionsAPI(Profile* profile) {
187 return true; 553 }
188 } 554
189 555 SessionsAPI::~SessionsAPI() {
190 // Check if the recently closed list contains an entry with the provided id. 556 }
191 bool is_valid_id = false; 557
192 for (TabRestoreService::Entries::iterator it = entries.begin(); 558 static base::LazyInstance<ProfileKeyedAPIFactory<SessionsAPI> >
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; 559 g_factory = LAZY_INSTANCE_INITIALIZER;
232 560
233 // static 561 // static
234 ProfileKeyedAPIFactory<SessionRestoreAPI>* 562 ProfileKeyedAPIFactory<SessionsAPI>*
235 SessionRestoreAPI::GetFactoryInstance() { 563 SessionsAPI::GetFactoryInstance() {
236 return &g_factory.Get(); 564 return &g_factory.Get();
237 } 565 }
238 566
239 } // namespace extensions 567 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698