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

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: Set similarity 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/strings/string_number_conversions.h" 11 #include "base/strings/string_number_conversions.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/extensions/extension_function_dispatcher.h"
13 #include "chrome/browser/extensions/extension_function_registry.h" 14 #include "chrome/browser/extensions/extension_function_registry.h"
14 #include "chrome/browser/extensions/extension_tab_util.h" 15 #include "chrome/browser/extensions/extension_tab_util.h"
16 #include "chrome/browser/extensions/window_controller.h"
17 #include "chrome/browser/extensions/window_controller_list.h"
15 #include "chrome/browser/profiles/profile.h" 18 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/sessions/session_restore.h" 19 #include "chrome/browser/sessions/session_restore.h"
17 #include "chrome/browser/sessions/tab_restore_service_delegate.h" 20 #include "chrome/browser/sessions/tab_restore_service_delegate.h"
18 #include "chrome/browser/sessions/tab_restore_service_factory.h" 21 #include "chrome/browser/sessions/tab_restore_service_factory.h"
19 #include "chrome/browser/sync/glue/session_model_associator.h" 22 #include "chrome/browser/sync/glue/session_model_associator.h"
20 #include "chrome/browser/sync/glue/synced_session.h" 23 #include "chrome/browser/sync/glue/synced_session.h"
21 #include "chrome/browser/sync/profile_sync_service.h" 24 #include "chrome/browser/sync/profile_sync_service.h"
22 #include "chrome/browser/sync/profile_sync_service_factory.h" 25 #include "chrome/browser/sync/profile_sync_service_factory.h"
23 #include "chrome/browser/ui/browser.h" 26 #include "chrome/browser/ui/browser.h"
24 #include "chrome/browser/ui/browser_finder.h" 27 #include "chrome/browser/ui/browser_finder.h"
25 #include "chrome/browser/ui/host_desktop.h" 28 #include "chrome/browser/ui/host_desktop.h"
26 #include "chrome/browser/ui/tabs/tab_strip_model.h" 29 #include "chrome/browser/ui/tabs/tab_strip_model.h"
27 #include "content/public/browser/web_contents.h" 30 #include "content/public/browser/web_contents.h"
31 #include "extensions/common/error_utils.h"
28 #include "ui/base/layout.h" 32 #include "ui/base/layout.h"
29 33
30
31 namespace { 34 namespace {
32 35
33 const unsigned int kMaxRecentlyClosedSessionResults = 25; 36 const unsigned int kMaxRecentlyClosedSessionResults = 25;
34 const char kRecentlyClosedListEmpty[] = 37 const unsigned int kMaxSyncedSessionResults = 10;
38 const char kRecentlyClosedListEmptyError[] =
35 "There are no recently closed sessions."; 39 "There are no recently closed sessions.";
36 const char kInvalidSessionId[] = "Invalid session id."; 40 const char kInvalidSessionIdError[] = "Invalid session id.";
37 const char kNoBrowserToRestoreSession[] = 41 const char kNoBrowserToRestoreSession[] =
38 "There are no browser windows to restore the session."; 42 "There are no browser windows to restore the session.";
43 const char kSessionsSyncNotEnabledError[] = "Syncing sessions is not enabled.";
44 const char kSyncedSessionsListEmptyError[] = "There are no foreign sessions.";
45 const char kSessionNotFoundError[] = "Session is not found.";
46 const char kSessionSyncError[] = "Session sync error.";
47 const char kForeignIdSeparator = '.';
48
49 const char kReturnObjectError[] = "Error returning window or tab.";
50 const char kWindowNotFoundError[] = "No window with id: *.";
51 const char kNoCurrentWindowError[] = "No current window.";
52 const char kWindowRestoreError[] = "Error restoring foreign window.";
53
54 std::string CreateForeignId(const std::string& session_tag, int id) {
55 return (session_tag + kForeignIdSeparator + base::IntToString(id));
56 }
not at google - send to devlin 2013/08/06 19:04:09 Rather than sharing a magic variable (kForeignIdSe
Kristen Dwan 2013/08/12 15:11:30 Done.
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 bool GetWindowFromWindowID(UIThreadExtensionFunction* function,
66 int window_id,
67 extensions::WindowController** controller) {
not at google - send to devlin 2013/08/06 19:04:09 Please pull this into a common place and share it
Kristen Dwan 2013/08/12 15:11:30 Done.
68 if (window_id == extension_misc::kCurrentWindowId) {
69 extensions::WindowController* extension_window_controller =
70 function->dispatcher()->delegate()->GetExtensionWindowController();
71 // If there is a window controller associated with this extension, use that.
72 if (extension_window_controller) {
73 *controller = extension_window_controller;
74 } else {
75 // Otherwise get the focused or most recently added window.
76 *controller = extensions::WindowControllerList::GetInstance()->
77 CurrentWindowForFunction(function);
78 }
79 if (!(*controller)) {
80 function->SetError(kNoCurrentWindowError);
81 return false;
82 }
83 } else {
84 *controller = extensions::WindowControllerList::GetInstance()->
85 FindWindowForFunctionById(function, window_id);
86 if (!(*controller)) {
87 function->SetError(extensions::ErrorUtils::FormatErrorMessage(
88 kWindowNotFoundError, base::IntToString(window_id)));
89 return false;
90 }
91 }
92 return true;
93 }
94
95 bool IsLocalSession(const std::string& id) {
96 return (id.find(kForeignIdSeparator) == std::string::npos);
97 }
98
99 bool SplitId(const std::string& sid, std::string* session_tag, int* id) {
100 std::size_t separator_index = sid.find(kForeignIdSeparator);
101 *session_tag = sid.substr(0, separator_index);
102 if (!base::StringToInt(sid.substr(separator_index + 1), id))
103 return false;
104 return true;
105 }
39 106
40 } // namespace 107 } // namespace
41 108
42 namespace extensions { 109 namespace extensions {
43 110
44 namespace GetRecentlyClosed = api::session_restore::GetRecentlyClosed; 111 namespace GetRecentlyClosed = api::sessions::GetRecentlyClosed;
45 namespace Restore = api::session_restore::Restore; 112 namespace GetDevices = api::sessions::GetDevices;
113 namespace Restore = api::sessions::Restore;
46 namespace tabs = api::tabs; 114 namespace tabs = api::tabs;
47 namespace windows = api::windows; 115 namespace windows = api::windows;
48 namespace session_restore = api::session_restore;
49 116
50 scoped_ptr<tabs::Tab> SessionRestoreGetRecentlyClosedFunction::CreateTabModel( 117 scoped_ptr<tabs::Tab> SessionsGetRecentlyClosedFunction::CreateTabModel(
51 const TabRestoreService::Tab& tab, int selected_index) { 118 const TabRestoreService::Tab& tab, const int* const session_id,
not at google - send to devlin 2013/08/06 19:04:09 The second const isn't necessary. That said I thi
Kristen Dwan 2013/08/12 15:11:30 Done.
119 int selected_index) {
52 scoped_ptr<tabs::Tab> tab_struct(new tabs::Tab); 120 scoped_ptr<tabs::Tab> tab_struct(new tabs::Tab);
53 const sessions::SerializedNavigationEntry& current_navigation = 121 const sessions::SerializedNavigationEntry& current_navigation =
54 tab.navigations[tab.current_navigation_index]; 122 tab.navigations[tab.current_navigation_index];
55 GURL gurl = current_navigation.virtual_url(); 123 GURL gurl = current_navigation.virtual_url();
56 std::string title = UTF16ToUTF8(current_navigation.title()); 124 std::string title = UTF16ToUTF8(current_navigation.title());
57 125
126 if (session_id) {
127 tab_struct->session_id.reset(
128 new std::string(base::IntToString(*session_id)));
129 } else {
130 tab_struct->session_id.reset(
131 new std::string(base::IntToString(tab.id)));
132 }
58 tab_struct->url.reset(new std::string(gurl.spec())); 133 tab_struct->url.reset(new std::string(gurl.spec()));
59 tab_struct->title.reset(new std::string(title.empty() ? gurl.spec() : title)); 134 tab_struct->title.reset(new std::string(title.empty() ? gurl.spec() : title));
60 tab_struct->index = tab.tabstrip_index; 135 tab_struct->index = tab.tabstrip_index;
61 tab_struct->pinned = tab.pinned; 136 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; 137 tab_struct->index = tab.tabstrip_index;
65 tab_struct->pinned = tab.pinned; 138 tab_struct->pinned = tab.pinned;
66 tab_struct->selected = tab.tabstrip_index == selected_index; 139 tab_struct->selected = tab.tabstrip_index == selected_index;
67 tab_struct->active = false; 140 tab_struct->active = false;
68 tab_struct->highlighted = false; 141 tab_struct->highlighted = false;
69 tab_struct->incognito = false; 142 tab_struct->incognito = false;
70 ExtensionTabUtil::ScrubTabForExtension(GetExtension(), 143 ExtensionTabUtil::ScrubTabForExtension(GetExtension(),
71 tab_struct.get()); 144 tab_struct.get());
72 return tab_struct.Pass(); 145 return tab_struct.Pass();
73 } 146 }
74 147
75 scoped_ptr<windows::Window> 148 scoped_ptr<windows::Window>
76 SessionRestoreGetRecentlyClosedFunction::CreateWindowModel( 149 SessionsGetRecentlyClosedFunction::CreateWindowModel(
77 const TabRestoreService::Window& window) { 150 const TabRestoreService::Window& window, int session_id) {
78 scoped_ptr<windows::Window> window_struct(new windows::Window); 151 scoped_ptr<windows::Window> window_struct(new windows::Window);
79 DCHECK(!window.tabs.empty()); 152 DCHECK(!window.tabs.empty());
80 153
81 scoped_ptr<std::vector<linked_ptr<tabs::Tab> > > tabs( 154 scoped_ptr<std::vector<linked_ptr<tabs::Tab> > > tabs(
82 new std::vector<linked_ptr<tabs::Tab> >); 155 new std::vector<linked_ptr<tabs::Tab> >);
83 for (size_t i = 0; i < window.tabs.size(); ++i) { 156 for (size_t i = 0; i < window.tabs.size(); ++i) {
84 tabs->push_back(make_linked_ptr(CreateTabModel(window.tabs[i], 157 tabs->push_back(make_linked_ptr(CreateTabModel(window.tabs[i], NULL,
85 window.selected_tab_index).release())); 158 window.selected_tab_index).release()));
86 } 159 }
160 window_struct->session_id.reset(
161 new std::string(base::IntToString(session_id)));
87 window_struct->tabs.reset(tabs.release()); 162 window_struct->tabs.reset(tabs.release());
88 window_struct->incognito = false; 163 window_struct->incognito = false;
89 window_struct->always_on_top = false; 164 window_struct->always_on_top = false;
90 window_struct->focused = false; 165 window_struct->focused = false;
91 window_struct->type = windows::Window::TYPE_NORMAL; 166 window_struct->type = windows::Window::TYPE_NORMAL;
92 window_struct->state = windows::Window::STATE_NORMAL; 167 window_struct->state = windows::Window::STATE_NORMAL;
93 return window_struct.Pass(); 168 return window_struct.Pass();
94 } 169 }
95 170
96 scoped_ptr<session_restore::ClosedEntry> 171 scoped_ptr<api::sessions::Session>
97 SessionRestoreGetRecentlyClosedFunction::CreateEntryModel( 172 SessionsGetRecentlyClosedFunction::CreateSessionModel(
98 const TabRestoreService::Entry* entry) { 173 const TabRestoreService::Entry* entry) {
99 scoped_ptr<session_restore::ClosedEntry> entry_struct( 174 scoped_ptr<api::sessions::Session> session_struct(new api::sessions::Session);
100 new session_restore::ClosedEntry);
101 switch (entry->type) { 175 switch (entry->type) {
102 case TabRestoreService::TAB: 176 case TabRestoreService::TAB:
103 entry_struct->tab.reset(CreateTabModel( 177 session_struct->tab.reset(CreateTabModel(
104 *static_cast<const TabRestoreService::Tab*>(entry), -1).release()); 178 *static_cast<const TabRestoreService::Tab*>(entry), &entry->id, -1)
179 .release());
105 break; 180 break;
106 case TabRestoreService::WINDOW: 181 case TabRestoreService::WINDOW:
107 entry_struct->window.reset(CreateWindowModel( 182 session_struct->window.reset(CreateWindowModel(
108 *static_cast<const TabRestoreService::Window*>(entry)).release()); 183 *static_cast<const TabRestoreService::Window*>(entry), entry->id)
184 .release());
109 break; 185 break;
110 default: 186 default:
111 NOTREACHED(); 187 NOTREACHED();
112 } 188 }
113 entry_struct->timestamp = entry->timestamp.ToTimeT(); 189 session_struct->last_modified = entry->timestamp.ToTimeT();
114 entry_struct->id = entry->id; 190 return session_struct.Pass();
115 return entry_struct.Pass();
116 } 191 }
117 192
118 bool SessionRestoreGetRecentlyClosedFunction::RunImpl() { 193 bool SessionsGetRecentlyClosedFunction::RunImpl() {
119 scoped_ptr<GetRecentlyClosed::Params> params( 194 scoped_ptr<GetRecentlyClosed::Params> params(
120 GetRecentlyClosed::Params::Create(*args_)); 195 GetRecentlyClosed::Params::Create(*args_));
121 EXTENSION_FUNCTION_VALIDATE(params.get()); 196 EXTENSION_FUNCTION_VALIDATE(params.get());
122 unsigned int max_results = kMaxRecentlyClosedSessionResults; 197 unsigned int max_results = kMaxRecentlyClosedSessionResults;
123 if (params->options && params->options->max_results) 198 if (params->options && params->options->max_results)
124 max_results = *params->options->max_results; 199 max_results = *params->options->max_results;
125 EXTENSION_FUNCTION_VALIDATE(max_results >= 0 && 200 EXTENSION_FUNCTION_VALIDATE(max_results >= 0 &&
126 max_results <= kMaxRecentlyClosedSessionResults); 201 max_results <= kMaxRecentlyClosedSessionResults);
127 202
128 std::vector<linked_ptr<session_restore::ClosedEntry> > result; 203 std::vector<linked_ptr<api::sessions::Session> > result;
129 TabRestoreService* tab_restore_service = 204 TabRestoreService* tab_restore_service =
130 TabRestoreServiceFactory::GetForProfile(profile()); 205 TabRestoreServiceFactory::GetForProfile(profile());
131 DCHECK(tab_restore_service); 206 DCHECK(tab_restore_service);
132 207
133 // List of entries. They are ordered from most to least recent. 208 // 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 209 // We prune the list to contain max 25 entries at any time and removes
135 // uninteresting entries. 210 // uninteresting entries.
136 TabRestoreService::Entries entries = tab_restore_service->entries(); 211 TabRestoreService::Entries entries = tab_restore_service->entries();
137 for (TabRestoreService::Entries::const_iterator it = entries.begin(); 212 for (TabRestoreService::Entries::const_iterator it = entries.begin();
138 it != entries.end() && result.size() < max_results; ++it) { 213 it != entries.end() && result.size() < max_results; ++it) {
139 TabRestoreService::Entry* entry = *it; 214 TabRestoreService::Entry* entry = *it;
140 if (!params->options || params->options->entry_type == 215 if (!params->options || params->options->entry_type ==
141 GetRecentlyClosed::Params::Options::ENTRY_TYPE_NONE) { 216 GetRecentlyClosed::Params::Options::ENTRY_TYPE_NONE) {
142 // Include both tabs and windows if type is not defined. 217 // Include both tabs and windows if type is not defined.
143 result.push_back(make_linked_ptr(CreateEntryModel(entry).release())); 218 result.push_back(make_linked_ptr(CreateSessionModel(entry).release()));
144 } else if ( 219 } else if (
145 (params->options->entry_type == 220 (params->options->entry_type ==
146 GetRecentlyClosed::Params::Options::ENTRY_TYPE_TAB && 221 GetRecentlyClosed::Params::Options::ENTRY_TYPE_TAB &&
147 entry->type == TabRestoreService::TAB) || 222 entry->type == TabRestoreService::TAB) ||
148 (params->options->entry_type == 223 (params->options->entry_type ==
149 GetRecentlyClosed::Params::Options::ENTRY_TYPE_WINDOW && 224 GetRecentlyClosed::Params::Options::ENTRY_TYPE_WINDOW &&
150 entry->type == TabRestoreService::WINDOW)) { 225 entry->type == TabRestoreService::WINDOW)) {
151 result.push_back(make_linked_ptr(CreateEntryModel(entry).release())); 226 result.push_back(make_linked_ptr(CreateSessionModel(entry).release()));
152 } 227 }
153 } 228 }
154 229
155 results_ = GetRecentlyClosed::Results::Create(result); 230 results_ = GetRecentlyClosed::Results::Create(result);
156 return true; 231 return true;
157 } 232 }
158 233
159 bool SessionRestoreRestoreFunction::RunImpl() { 234 scoped_ptr<tabs::Tab> SessionsGetDevicesFunction::CreateTabModel(
not at google - send to devlin 2013/08/06 19:04:09 what's the difference between this and the other C
Kristen Dwan 2013/08/12 15:11:30 This takes a SessionTab and the other takes a TabR
160 scoped_ptr<Restore::Params> params(Restore::Params::Create(*args_)); 235 const SessionTab& tab, int selected_index, int tab_index,
236 const std::string& session_tag) {
237 scoped_ptr<tabs::Tab> tab_struct(new tabs::Tab);
238 const sessions::SerializedNavigationEntry& current_navigation =
239 tab.navigations[tab.current_navigation_index];
240 const GURL& gurl = current_navigation.virtual_url();
241 std::string title = UTF16ToUTF8(current_navigation.title());
242
243 tab_struct->session_id.reset(
244 new std::string(CreateForeignId(session_tag, tab.tab_id.id())));
245 tab_struct->url.reset(new std::string(gurl.spec()));
246 tab_struct->title.reset(new std::string(title.empty() ? gurl.spec() : title));
247 tab_struct->pinned = tab.pinned;
248 tab_struct->index = tab_index;
249 tab_struct->pinned = tab.pinned;
250 tab_struct->selected = tab_index == selected_index;
251 tab_struct->active = false;
252 tab_struct->highlighted = false;
253 tab_struct->incognito = false;
254 ExtensionTabUtil::ScrubTabForExtension(GetExtension(), tab_struct.get());
255 return tab_struct.Pass();
256 }
257
258 scoped_ptr<windows::Window> SessionsGetDevicesFunction::CreateWindowModel(
not at google - send to devlin 2013/08/06 19:04:09 ditto?
Kristen Dwan 2013/08/12 15:11:30 SessionWindow VS TabRestoreService::Window. Chang
259 const SessionWindow& window, const std::string& session_tag) {
260 scoped_ptr<windows::Window> window_struct(new windows::Window);
261 DCHECK(!window.tabs.empty());
262
263 scoped_ptr<std::vector<linked_ptr<tabs::Tab> > > tabs(
264 new std::vector<linked_ptr<tabs::Tab> >);
265 for (size_t i = 0; i < window.tabs.size(); ++i) {
266 tabs->push_back(make_linked_ptr(
267 CreateTabModel(*window.tabs[i], window.selected_tab_index, i,
268 session_tag).release()));
269 }
270 window_struct->tabs = tabs.Pass();
271
272 window_struct->session_id.reset(
273 new std::string(CreateForeignId(session_tag, window.window_id.id())));
274 window_struct->left.reset(new int(window.bounds.x()));
275 window_struct->top.reset(new int(window.bounds.y()));
276 window_struct->width.reset(new int(window.bounds.width()));
277 window_struct->height.reset(new int(window.bounds.height()));
278 window_struct->incognito = false;
279 window_struct->always_on_top = false;
280 window_struct->focused = false;
281
282 switch (window.type) {
283 case Browser::TYPE_TABBED:
284 window_struct->type = windows::Window::TYPE_NORMAL;
285 break;
286 case Browser::TYPE_POPUP:
287 window_struct->type = windows::Window::TYPE_POPUP;
288 break;
289 default:
290 window_struct->type = windows::Window::TYPE_NONE;
291 }
292
293 switch (window.show_state) {
294 case ui::SHOW_STATE_NORMAL:
295 window_struct->state = windows::Window::STATE_NORMAL;
296 break;
297 case ui::SHOW_STATE_MINIMIZED:
298 window_struct->state = windows::Window::STATE_MINIMIZED;
299 break;
300 case ui::SHOW_STATE_MAXIMIZED:
301 window_struct->state = windows::Window::STATE_MAXIMIZED;
302 break;
303 case ui::SHOW_STATE_FULLSCREEN:
304 window_struct->state = windows::Window::STATE_FULLSCREEN;
305 break;
306 default:
307 window_struct->state = windows::Window::STATE_NONE;
308 }
309 return window_struct.Pass();
310 }
311
312 scoped_ptr<api::sessions::Session>
313 SessionsGetDevicesFunction::CreateSessionModel(
not at google - send to devlin 2013/08/06 19:04:09 ditto?
Kristen Dwan 2013/08/12 15:11:30 SessionWindow vs. TabRestoreService::Entry*. put i
314 const SessionWindow& window, const std::string& session_tag) {
315 scoped_ptr<api::sessions::Session> session_struct(new api::sessions::Session);
316 session_struct->last_modified = window.timestamp.ToTimeT();
317 session_struct->window.reset(
318 CreateWindowModel(window, session_tag).release());
319 return session_struct.Pass();
320 }
321
322 scoped_ptr<api::sessions::Device> SessionsGetDevicesFunction::CreateDeviceModel(
323 const browser_sync::SyncedSession* session) {
324 scoped_ptr<api::sessions::Device> device_struct(new api::sessions::Device);
325 device_struct->info = session->session_name;
326
327 for (browser_sync::SyncedSession::SyncedWindowMap::const_iterator it =
328 session->windows.begin(); it != session->windows.end(); ++it) {
329 device_struct->sessions.push_back(make_linked_ptr(CreateSessionModel(
330 *it->second, session->session_tag).release()));
331 }
332 return device_struct.Pass();
333 }
334
335 bool SessionsGetDevicesFunction::RunImpl() {
336 ProfileSyncService* service =
337 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile());
338 if (!(service && service->GetPreferredDataTypes().Has(syncer::SESSIONS))) {
339 SetError(kSessionsSyncNotEnabledError);
not at google - send to devlin 2013/08/06 19:04:09 Not sure about this one. There should be a way for
Kristen Dwan 2013/08/12 15:11:30 I can't think of anything that would be clean and
not at google - send to devlin 2013/08/12 23:51:34 This sounds good to me.
340 return false;
341 }
342 unsigned int max_results = kMaxSyncedSessionResults;
not at google - send to devlin 2013/08/06 19:04:09 just "int".
Kristen Dwan 2013/08/12 15:11:30 Done.
343 scoped_ptr<GetDevices::Params> params(
344 GetDevices::Params::Create(*args_));
not at google - send to devlin 2013/08/06 19:04:09 1 line?
Kristen Dwan 2013/08/12 15:11:30 Done.
161 EXTENSION_FUNCTION_VALIDATE(params.get()); 345 EXTENSION_FUNCTION_VALIDATE(params.get());
346 if (params->max_results.get())
347 max_results = *params->max_results.get();
348 EXTENSION_FUNCTION_VALIDATE(max_results >= 0 &&
349 max_results <= kMaxSyncedSessionResults);
162 350
163 Browser* browser = 351 browser_sync::SessionModelAssociator* associator =
164 chrome::FindBrowserWithProfile(profile(), 352 service->GetSessionModelAssociator();
165 chrome::HOST_DESKTOP_TYPE_NATIVE); 353 std::vector<const browser_sync::SyncedSession*> sessions;
166 if (!browser) { 354 if (!associator) {
167 error_ = kNoBrowserToRestoreSession; 355 SetError(kSessionSyncError);
356 return false;
357 }
358 if (!associator->GetAllForeignSessions(&sessions)) {
359 SetError(kSyncedSessionsListEmptyError);
not at google - send to devlin 2013/08/06 19:04:09 This isn't really an *error* case. Similar as befo
Kristen Dwan 2013/08/12 15:11:30 would you recommend just returning true here then
not at google - send to devlin 2013/08/12 23:51:34 empty results seems consistent.
168 return false; 360 return false;
169 } 361 }
170 362
363 std::vector<linked_ptr<api::sessions::Device> > result;
364 // Sort sessions from most recent to least recent.
365 std::sort(sessions.begin(), sessions.end(), SortSessionsByRecency);
366 for (size_t i = 0; i < sessions.size() && result.size() < max_results; ++i) {
367 result.push_back(make_linked_ptr(CreateDeviceModel(sessions[i]).release()));
368 }
369
370 results_ = GetDevices::Results::Create(result);
371 return true;
372 }
373
374 bool SessionsRestoreFunction::RestoreMostRecentlyClosed(Browser* browser) {
171 TabRestoreService* tab_restore_service = 375 TabRestoreService* tab_restore_service =
172 TabRestoreServiceFactory::GetForProfile(profile()); 376 TabRestoreServiceFactory::GetForProfile(profile());
173 TabRestoreServiceDelegate* delegate = 377 TabRestoreServiceDelegate* delegate =
174 TabRestoreServiceDelegate::FindDelegateForWebContents( 378 TabRestoreServiceDelegate::FindDelegateForWebContents(
175 browser->tab_strip_model()->GetActiveWebContents()); 379 browser->tab_strip_model()->GetActiveWebContents());
176 DCHECK(delegate); 380 DCHECK(delegate);
177 chrome::HostDesktopType host_desktop_type = browser->host_desktop_type(); 381 chrome::HostDesktopType host_desktop_type = browser->host_desktop_type();
178 TabRestoreService::Entries entries = tab_restore_service->entries(); 382 TabRestoreService::Entries entries = tab_restore_service->entries();
179 383
180 if (entries.empty()) { 384 if (entries.empty()) {
181 error_ = kRecentlyClosedListEmpty; 385 SetError(kRecentlyClosedListEmptyError);
not at google - send to devlin 2013/08/06 19:04:09 also not an error - and this function shouldn't be
Kristen Dwan 2013/08/12 15:11:30 this is how the current sessionRestore api impleme
not at google - send to devlin 2013/08/12 23:51:34 Yeah ok I might have gotten carried away with maki
182 return false; 386 return false;
183 } 387 }
184 388
185 if (!params->id) { 389 bool is_window = entries.front()->type == TabRestoreService::WINDOW;
not at google - send to devlin 2013/08/06 19:04:09 inline this?
Kristen Dwan 2013/08/12 15:11:30 Done.
186 tab_restore_service->RestoreMostRecentEntry(delegate, host_desktop_type); 390 std::vector<content::WebContents*> contents =
187 return true; 391 tab_restore_service->RestoreMostRecentEntry(delegate, host_desktop_type);
392 if (!contents.size()) {
393 SetError(kReturnObjectError);
not at google - send to devlin 2013/08/06 19:04:09 I think we can do a better job of an error message
Kristen Dwan 2013/08/12 15:11:30 got rid of this. backend calls are always returnin
394 return false;
395 }
396
397 if (is_window) {
398 WindowController* controller;
not at google - send to devlin 2013/08/06 19:04:09 always initialise pointers to NULL in situations l
Kristen Dwan 2013/08/12 15:11:30 Done.
399 if (!GetWindowFromWindowID(this,
400 ExtensionTabUtil::GetWindowIdOfTab(contents[0]),
401 &controller))
402 return false;
not at google - send to devlin 2013/08/06 19:04:09 error message
Kristen Dwan 2013/08/12 15:11:30 Done.
403 SetResult(controller->CreateWindowValueWithTabs(GetExtension()));
404 } else {
405 SetResult(ExtensionTabUtil::CreateTabValue(contents[0], GetExtension()));
406 }
407 return true;
408 }
409
410 bool SessionsRestoreFunction::RestoreLocalSession(int id, Browser* browser) {
411 TabRestoreService* tab_restore_service =
412 TabRestoreServiceFactory::GetForProfile(profile());
413 TabRestoreServiceDelegate* delegate =
414 TabRestoreServiceDelegate::FindDelegateForWebContents(
415 browser->tab_strip_model()->GetActiveWebContents());
not at google - send to devlin 2013/08/06 19:04:09 delegate isn't used until way later, grab it then.
Kristen Dwan 2013/08/12 15:11:30 "|delegate| will be NULL in cases where one isn't
416 DCHECK(delegate);
417 chrome::HostDesktopType host_desktop_type = browser->host_desktop_type();
418 TabRestoreService::Entries entries = tab_restore_service->entries();
419
420 if (entries.empty()) {
421 SetError(kRecentlyClosedListEmptyError);
422 return false;
188 } 423 }
189 424
190 // Check if the recently closed list contains an entry with the provided id. 425 // Check if the recently closed list contains an entry with the provided id.
191 bool is_valid_id = false; 426 bool is_valid_id = false;
427 bool is_window = false;
not at google - send to devlin 2013/08/06 19:04:09 rather than hold onto these two values, perhaps fi
Kristen Dwan 2013/08/12 15:11:30 https://code.google.com/p/chromium/codesearch#chro
192 for (TabRestoreService::Entries::iterator it = entries.begin(); 428 for (TabRestoreService::Entries::iterator it = entries.begin();
193 it != entries.end(); ++it) { 429 it != entries.end(); ++it) {
194 if ((*it)->id == *params->id) { 430 if ((*it)->id == id) {
195 is_valid_id = true; 431 is_valid_id = true;
432 // The only time a full window is being restored is if the entry ID
433 // matches the provided ID and the entry type is Window.
434 is_window = (*it)->type == TabRestoreService::WINDOW;
196 break; 435 break;
197 } 436 }
198
199 // For Window entries, see if the ID matches a tab. If so, report true for 437 // For Window entries, see if the ID matches a tab. If so, report true for
200 // the window as the Entry. 438 // the window as the Entry.
201 if ((*it)->type == TabRestoreService::WINDOW) { 439 if ((*it)->type == TabRestoreService::WINDOW) {
202 std::vector<TabRestoreService::Tab>& tabs = 440 std::vector<TabRestoreService::Tab>& tabs =
203 static_cast<TabRestoreService::Window*>(*it)->tabs; 441 static_cast<TabRestoreService::Window*>(*it)->tabs;
204 for (std::vector<TabRestoreService::Tab>::iterator tab_it = tabs.begin(); 442 for (std::vector<TabRestoreService::Tab>::iterator tab_it = tabs.begin();
205 tab_it != tabs.end(); ++tab_it) { 443 tab_it != tabs.end(); ++tab_it) {
206 if ((*tab_it).id == *params->id) { 444 if ((*tab_it).id == id) {
207 is_valid_id = true; 445 is_valid_id = true;
208 break; 446 break;
209 } 447 }
210 } 448 }
211 } 449 }
212 } 450 }
213 451
214 if (!is_valid_id) { 452 if (!is_valid_id) {
215 error_ = kInvalidSessionId; 453 SetError(kInvalidSessionIdError);
216 return false; 454 return false;
217 } 455 }
218 456
219 tab_restore_service->RestoreEntryById(delegate, *params->id, 457 std::vector<content::WebContents*> contents =
220 host_desktop_type, UNKNOWN); 458 tab_restore_service->RestoreEntryById(delegate, id, host_desktop_type,
459 UNKNOWN);
460 if (!contents.size()) {
461 SetError(kReturnObjectError);
not at google - send to devlin 2013/08/06 19:04:09 yeah so kReturnObject error - not a great error in
Kristen Dwan 2013/08/12 15:11:30 got rid of it.
462 return false;
463 }
464
465 if (is_window) {
466 WindowController* controller;
467 if (!GetWindowFromWindowID(this,
468 ExtensionTabUtil::GetWindowIdOfTab(contents[0]),
469 &controller))
470 return false;
471 SetResult(controller->CreateWindowValueWithTabs(GetExtension()));
472 } else {
473 SetResult(ExtensionTabUtil::CreateTabValue(contents[0], GetExtension()));
474 }
475
221 return true; 476 return true;
222 } 477 }
223 478
224 SessionRestoreAPI::SessionRestoreAPI(Profile* profile) { 479 bool SessionsRestoreFunction::RestoreForeignSession(
480 const std::string& session_tag, int id, Browser* browser) {
not at google - send to devlin 2013/08/06 19:04:09 similar comments throughout here and the next func
Kristen Dwan 2013/08/12 15:11:30 Done.
481 ProfileSyncService* service =
482 ProfileSyncServiceFactory::GetInstance()->GetForProfile(profile());
483 if (!(service && service->GetPreferredDataTypes().Has(syncer::SESSIONS))) {
484 SetError(kSessionsSyncNotEnabledError);
Kristen Dwan 2013/08/12 15:11:30 Would you agree that these sync errors in restore
485 return false;
486 }
487 browser_sync::SessionModelAssociator* associator =
488 service->GetSessionModelAssociator();
489 if (!associator) {
490 SetError(kSessionSyncError);
491 return false;
492 }
493
494 const SessionTab* tab = NULL;
495 if (associator->GetForeignTab(session_tag, id, &tab)) {
496 TabStripModel* tab_strip = browser->tab_strip_model();
497 content::WebContents* contents = tab_strip->GetActiveWebContents();
498
499 content::WebContents* tab_content =
500 SessionRestore::RestoreForeignSessionTab(contents, *tab,
501 NEW_FOREGROUND_TAB);
502 SetResult(ExtensionTabUtil::CreateTabValue(tab_content, GetExtension()));
503 return true;
504 } else {
not at google - send to devlin 2013/08/06 19:04:09 no else after return
Kristen Dwan 2013/08/12 15:11:30 Done.
505 std::vector<const SessionWindow*> windows;
506 if (!associator->GetForeignSession(session_tag, &windows)) {
507 SetError(kSessionNotFoundError);
508 return false;
509 }
510
511 std::vector<const SessionWindow*>::const_iterator window = windows.begin();
512 while (window != windows.end() && (*window)->window_id.id() != id) {
513 ++window;
514 }
515 if (window == windows.end()) {
516 SetError(kSessionNotFoundError);
517 return false;
518 }
519
520 chrome::HostDesktopType host_desktop_type = browser->host_desktop_type();
521 // Only restore one window at a time.
522 std::vector<Browser*> browser =
523 SessionRestore::RestoreForeignSessionWindows(profile(),
524 host_desktop_type, window, (window + 1));
525 if (browser.size() != 1) {
526 SetError(kWindowRestoreError);
527 return false;
528 }
529
530 WindowController* controller;
531 if (!GetWindowFromWindowID(this,
532 ExtensionTabUtil::GetWindowId(browser[0]),
533 &controller))
534 return false;
535 SetResult(controller->CreateWindowValueWithTabs(GetExtension()));
536 }
537
538 return true;
225 } 539 }
226 540
227 SessionRestoreAPI::~SessionRestoreAPI() { 541 bool SessionsRestoreFunction::RunImpl() {
542 scoped_ptr<Restore::Params> params(Restore::Params::Create(*args_));
543 EXTENSION_FUNCTION_VALIDATE(params.get());
544
545 Browser* browser =
546 chrome::FindBrowserWithProfile(profile(),
547 chrome::HOST_DESKTOP_TYPE_NATIVE);
548 if (!browser) {
549 SetError(kNoBrowserToRestoreSession);
550 return false;
551 }
552
553 if (!params->session_id)
554 return RestoreMostRecentlyClosed(browser);
555
556 if (IsLocalSession(*params->session_id)) {
557 int id;
558 if (!base::StringToInt(*params->session_id, &id)) {
559 SetError(kInvalidSessionIdError);
560 return false;
561 }
562 return RestoreLocalSession(id, browser);
563 } else {
564 std::string session_tag;
565 int id;
566 if (!SplitId(*params->session_id, &session_tag, &id)) {
567 SetError(kInvalidSessionIdError);
568 return false;
569 }
570 return RestoreForeignSession(session_tag, id, browser);
571 }
572
573 // Should never reach here.
574 return false;
228 } 575 }
229 576
230 static base::LazyInstance<ProfileKeyedAPIFactory<SessionRestoreAPI> > 577 SessionsAPI::SessionsAPI(Profile* profile) {
578 }
579
580 SessionsAPI::~SessionsAPI() {
581 }
582
583 static base::LazyInstance<ProfileKeyedAPIFactory<SessionsAPI> >
231 g_factory = LAZY_INSTANCE_INITIALIZER; 584 g_factory = LAZY_INSTANCE_INITIALIZER;
232 585
233 // static 586 // static
234 ProfileKeyedAPIFactory<SessionRestoreAPI>* 587 ProfileKeyedAPIFactory<SessionsAPI>*
235 SessionRestoreAPI::GetFactoryInstance() { 588 SessionsAPI::GetFactoryInstance() {
236 return &g_factory.Get(); 589 return &g_factory.Get();
237 } 590 }
238 591
239 } // namespace extensions 592 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698