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

Side by Side Diff: chrome/browser/sessions/session_service_commands.cc

Issue 672083002: Refactoring of SessionService to get componentized. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed Created 6 years, 1 month 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
OLDNEW
(Empty)
1 // Copyright 2014 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/sessions/session_service_commands.h"
6
7 #include <vector>
8
9 #include "base/pickle.h"
10 #include "chrome/browser/sessions/base_session_service_commands.h"
11 #include "chrome/browser/sessions/base_session_service_delegate.h"
12 #include "chrome/browser/sessions/session_command.h"
13 #include "chrome/browser/sessions/session_types.h"
14
15 // Identifier for commands written to file.
16 static const SessionCommand::id_type kCommandSetTabWindow = 0;
17 // OBSOLETE Superseded by kCommandSetWindowBounds3.
18 // static const SessionCommand::id_type kCommandSetWindowBounds = 1;
19 static const SessionCommand::id_type kCommandSetTabIndexInWindow = 2;
20 static const SessionCommand::id_type
21 kCommandTabNavigationPathPrunedFromBack = 5;
22 static const SessionCommand::id_type kCommandUpdateTabNavigation = 6;
23 static const SessionCommand::id_type kCommandSetSelectedNavigationIndex = 7;
24 static const SessionCommand::id_type kCommandSetSelectedTabInIndex = 8;
25 static const SessionCommand::id_type kCommandSetWindowType = 9;
26 // OBSOLETE Superseded by kCommandSetWindowBounds3. Except for data migration.
27 // static const SessionCommand::id_type kCommandSetWindowBounds2 = 10;
28 static const SessionCommand::id_type
29 kCommandTabNavigationPathPrunedFromFront = 11;
30 static const SessionCommand::id_type kCommandSetPinnedState = 12;
31 static const SessionCommand::id_type kCommandSetExtensionAppID = 13;
32 static const SessionCommand::id_type kCommandSetWindowBounds3 = 14;
33 static const SessionCommand::id_type kCommandSetWindowAppName = 15;
34 static const SessionCommand::id_type kCommandTabClosed = 16;
35 static const SessionCommand::id_type kCommandWindowClosed = 17;
36 static const SessionCommand::id_type kCommandSetTabUserAgentOverride = 18;
37 static const SessionCommand::id_type kCommandSessionStorageAssociated = 19;
38 static const SessionCommand::id_type kCommandSetActiveWindow = 20;
39
40 namespace {
41
42 // Various payload structures.
43 struct ClosedPayload {
44 SessionID::id_type id;
45 int64 close_time;
46 };
47
48 struct WindowBoundsPayload2 {
49 SessionID::id_type window_id;
50 int32 x;
51 int32 y;
52 int32 w;
53 int32 h;
54 bool is_maximized;
55 };
56
57 struct WindowBoundsPayload3 {
58 SessionID::id_type window_id;
59 int32 x;
60 int32 y;
61 int32 w;
62 int32 h;
63 int32 show_state;
64 };
65
66 typedef SessionID::id_type ActiveWindowPayload;
67
68 struct IDAndIndexPayload {
69 SessionID::id_type id;
70 int32 index;
71 };
72
73 typedef IDAndIndexPayload TabIndexInWindowPayload;
74
75 typedef IDAndIndexPayload TabNavigationPathPrunedFromBackPayload;
76
77 typedef IDAndIndexPayload SelectedNavigationIndexPayload;
78
79 typedef IDAndIndexPayload SelectedTabInIndexPayload;
80
81 typedef IDAndIndexPayload WindowTypePayload;
82
83 typedef IDAndIndexPayload TabNavigationPathPrunedFromFrontPayload;
84
85 struct PinnedStatePayload {
86 SessionID::id_type tab_id;
87 bool pinned_state;
88 };
89
90 // Persisted versions of ui::WindowShowState that are written to disk and can
91 // never change.
92 enum PersistedWindowShowState {
93 // SHOW_STATE_DEFAULT (0) never persisted.
94 PERSISTED_SHOW_STATE_NORMAL = 1,
95 PERSISTED_SHOW_STATE_MINIMIZED = 2,
96 PERSISTED_SHOW_STATE_MAXIMIZED = 3,
97 // SHOW_STATE_INACTIVE (4) never persisted.
98 PERSISTED_SHOW_STATE_FULLSCREEN = 5,
99 PERSISTED_SHOW_STATE_DETACHED_DEPRECATED = 6,
100 PERSISTED_SHOW_STATE_END = 6
101 };
102
103 // Assert to ensure PersistedWindowShowState is updated if ui::WindowShowState
104 // is changed.
105 COMPILE_ASSERT(ui::SHOW_STATE_END ==
106 static_cast<ui::WindowShowState>(PERSISTED_SHOW_STATE_END),
107 persisted_show_state_mismatch);
108
109 // Returns the show state to store to disk based |state|.
110 PersistedWindowShowState ShowStateToPersistedShowState(
111 ui::WindowShowState state) {
112 switch (state) {
113 case ui::SHOW_STATE_NORMAL:
114 return PERSISTED_SHOW_STATE_NORMAL;
115 case ui::SHOW_STATE_MINIMIZED:
116 return PERSISTED_SHOW_STATE_MINIMIZED;
117 case ui::SHOW_STATE_MAXIMIZED:
118 return PERSISTED_SHOW_STATE_MAXIMIZED;
119 case ui::SHOW_STATE_FULLSCREEN:
120 return PERSISTED_SHOW_STATE_FULLSCREEN;
121
122 case ui::SHOW_STATE_DEFAULT:
123 case ui::SHOW_STATE_INACTIVE:
124 return PERSISTED_SHOW_STATE_NORMAL;
125
126 case ui::SHOW_STATE_END:
127 break;
128 }
129 NOTREACHED();
130 return PERSISTED_SHOW_STATE_NORMAL;
131 }
132
133 // Lints show state values when read back from persited disk.
134 ui::WindowShowState PersistedShowStateToShowState(int state) {
135 switch (state) {
136 case PERSISTED_SHOW_STATE_NORMAL:
137 return ui::SHOW_STATE_NORMAL;
138 case PERSISTED_SHOW_STATE_MINIMIZED:
139 return ui::SHOW_STATE_MINIMIZED;
140 case PERSISTED_SHOW_STATE_MAXIMIZED:
141 return ui::SHOW_STATE_MAXIMIZED;
142 case PERSISTED_SHOW_STATE_FULLSCREEN:
143 return ui::SHOW_STATE_FULLSCREEN;
144 case PERSISTED_SHOW_STATE_DETACHED_DEPRECATED:
145 return ui::SHOW_STATE_NORMAL;
146 }
147 NOTREACHED();
148 return ui::SHOW_STATE_NORMAL;
149 }
150
151 } // namespace
152
153 // SessionService -------------------------------------------------------------
154
155 SessionServiceCommands::SessionServiceCommands() {}
156
157 SessionServiceCommands::~SessionServiceCommands() {
158 // The owner is responsible to save upon exit.
159 }
160
161 SessionCommand* SessionServiceCommands::CreateSetSelectedTabInWindowCommand(
162 const SessionID& window_id,
163 int index) {
164 SelectedTabInIndexPayload payload = { 0 };
165 payload.id = window_id.id();
166 payload.index = index;
167 SessionCommand* command = new SessionCommand(kCommandSetSelectedTabInIndex,
168 sizeof(payload));
169 memcpy(command->contents(), &payload, sizeof(payload));
170 return command;
171 }
172
173 SessionCommand* SessionServiceCommands::CreateSetTabWindowCommand(
174 const SessionID& window_id,
175 const SessionID& tab_id) {
176 SessionID::id_type payload[] = { window_id.id(), tab_id.id() };
177 SessionCommand* command =
178 new SessionCommand(kCommandSetTabWindow, sizeof(payload));
179 memcpy(command->contents(), payload, sizeof(payload));
180 return command;
181 }
182
183 SessionCommand* SessionServiceCommands::CreateSetWindowBoundsCommand(
184 const SessionID& window_id,
185 const gfx::Rect& bounds,
186 ui::WindowShowState show_state) {
187 WindowBoundsPayload3 payload = { 0 };
188 payload.window_id = window_id.id();
189 payload.x = bounds.x();
190 payload.y = bounds.y();
191 payload.w = bounds.width();
192 payload.h = bounds.height();
193 payload.show_state = ShowStateToPersistedShowState(show_state);
194 SessionCommand* command = new SessionCommand(kCommandSetWindowBounds3,
195 sizeof(payload));
196 memcpy(command->contents(), &payload, sizeof(payload));
197 return command;
198 }
199
200 SessionCommand* SessionServiceCommands::CreateSetTabIndexInWindowCommand(
201 const SessionID& tab_id,
202 int new_index) {
203 TabIndexInWindowPayload payload = { 0 };
204 payload.id = tab_id.id();
205 payload.index = new_index;
206 SessionCommand* command =
207 new SessionCommand(kCommandSetTabIndexInWindow, sizeof(payload));
208 memcpy(command->contents(), &payload, sizeof(payload));
209 return command;
210 }
211
212 SessionCommand* SessionServiceCommands::CreateTabClosedCommand(
213 const SessionID::id_type tab_id) {
214 ClosedPayload payload;
215 // Because of what appears to be a compiler bug setting payload to {0} doesn't
216 // set the padding to 0, resulting in Purify reporting an UMR when we write
217 // the structure to disk. To avoid this we explicitly memset the struct.
218 memset(&payload, 0, sizeof(payload));
219 payload.id = tab_id;
220 payload.close_time = base::Time::Now().ToInternalValue();
221 SessionCommand* command =
222 new SessionCommand(kCommandTabClosed, sizeof(payload));
223 memcpy(command->contents(), &payload, sizeof(payload));
224 return command;
225 }
226
227 SessionCommand* SessionServiceCommands::CreateWindowClosedCommand(
228 const SessionID::id_type window_id) {
229 ClosedPayload payload;
230 // See comment in CreateTabClosedCommand as to why we do this.
231 memset(&payload, 0, sizeof(payload));
232 payload.id = window_id;
233 payload.close_time = base::Time::Now().ToInternalValue();
234 SessionCommand* command =
235 new SessionCommand(kCommandWindowClosed, sizeof(payload));
236 memcpy(command->contents(), &payload, sizeof(payload));
237 return command;
238 }
239
240 SessionCommand* SessionServiceCommands::CreateSetSelectedNavigationIndexCommand(
241 const SessionID& tab_id,
242 int index) {
243 SelectedNavigationIndexPayload payload = { 0 };
244 payload.id = tab_id.id();
245 payload.index = index;
246 SessionCommand* command = new SessionCommand(
247 kCommandSetSelectedNavigationIndex, sizeof(payload));
248 memcpy(command->contents(), &payload, sizeof(payload));
249 return command;
250 }
251
252 SessionCommand* SessionServiceCommands::CreateSetWindowTypeCommand(
253 const SessionID& window_id,
254 SessionWindow::WindowType type) {
255 WindowTypePayload payload = { 0 };
256 payload.id = window_id.id();
257 payload.index = static_cast<int32>(type);
258 SessionCommand* command = new SessionCommand(
259 kCommandSetWindowType, sizeof(payload));
260 memcpy(command->contents(), &payload, sizeof(payload));
261 return command;
262 }
263
264 SessionCommand* SessionServiceCommands::CreatePinnedStateCommand(
265 const SessionID& tab_id,
266 bool is_pinned) {
267 PinnedStatePayload payload = { 0 };
268 payload.tab_id = tab_id.id();
269 payload.pinned_state = is_pinned;
270 SessionCommand* command =
271 new SessionCommand(kCommandSetPinnedState, sizeof(payload));
272 memcpy(command->contents(), &payload, sizeof(payload));
273 return command;
274 }
275
276 SessionCommand* SessionServiceCommands::CreateSessionStorageAssociatedCommand(
277 const SessionID& tab_id,
278 const std::string& session_storage_persistent_id) {
279 Pickle pickle;
280 pickle.WriteInt(tab_id.id());
281 pickle.WriteString(session_storage_persistent_id);
282 return new SessionCommand(kCommandSessionStorageAssociated, pickle);
283 }
284
285 SessionCommand* SessionServiceCommands::CreateSetActiveWindowCommand(
286 const SessionID& window_id) {
287 ActiveWindowPayload payload = 0;
288 payload = window_id.id();
289 SessionCommand* command =
290 new SessionCommand(kCommandSetActiveWindow, sizeof(payload));
291 memcpy(command->contents(), &payload, sizeof(payload));
292 return command;
293 }
294
295 SessionCommand*
296 SessionServiceCommands::CreateTabNavigationPathPrunedFromBackCommand(
297 const SessionID& tab_id,
298 int count) {
299 TabNavigationPathPrunedFromBackPayload payload = { 0 };
300 payload.id = tab_id.id();
301 payload.index = count;
302 SessionCommand* command =
303 new SessionCommand(kCommandTabNavigationPathPrunedFromBack,
304 sizeof(payload));
305 memcpy(command->contents(), &payload, sizeof(payload));
306 return command;
307 }
308
309 SessionCommand*
310 SessionServiceCommands::CreateTabNavigationPathPrunedFromFrontCommand(
311 const SessionID& tab_id,
312 int count) {
313 TabNavigationPathPrunedFromFrontPayload payload = { 0 };
314 payload.id = tab_id.id();
315 payload.index = count;
316 SessionCommand* command =
317 new SessionCommand(kCommandTabNavigationPathPrunedFromFront,
318 sizeof(payload));
319 memcpy(command->contents(), &payload, sizeof(payload));
320 return command;
321 }
322
323 SessionCommand* SessionServiceCommands::CreateUpdateTabNavigationCommand(
324 const SessionID& tab_id,
325 const sessions::SerializedNavigationEntry& navigation) {
326 return ::CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation,
327 tab_id.id(),
328 navigation);
329 }
330
331 SessionCommand* SessionServiceCommands::CreateSetTabExtensionAppIDCommand(
332 const SessionID& tab_id,
333 const std::string& extension_id) {
334 return ::CreateSetTabExtensionAppIDCommand(kCommandSetExtensionAppID,
335 tab_id.id(),
336 extension_id);
337 }
338
339 SessionCommand* SessionServiceCommands::CreateSetTabUserAgentOverrideCommand(
340 const SessionID& tab_id,
341 const std::string& user_agent_override) {
342 return ::CreateSetTabUserAgentOverrideCommand(kCommandSetTabUserAgentOverride,
343 tab_id.id(),
344 user_agent_override);
345 }
346
347 SessionCommand* SessionServiceCommands::CreateSetWindowAppNameCommand(
348 const SessionID& window_id,
349 const std::string& app_name) {
350 return ::CreateSetWindowAppNameCommand(kCommandSetWindowAppName,
351 window_id.id(),
352 app_name);
353 }
354
355 bool SessionServiceCommands::ReplacePendingCommand(
356 SessionCommand* command,
357 std::vector<SessionCommand*>& pending_commands) {
358 // We optimize page navigations, which can happen quite frequently and
359 // is expensive. And activation is like Highlander, there can only be one!
360 if (command->id() != kCommandUpdateTabNavigation &&
361 command->id() != kCommandSetActiveWindow) {
362 return false;
363 }
364 for (std::vector<SessionCommand*>::reverse_iterator i =
365 pending_commands.rbegin(); i != pending_commands.rend(); ++i) {
366 SessionCommand* existing_command = *i;
367 if (command->id() == kCommandUpdateTabNavigation &&
368 existing_command->id() == kCommandUpdateTabNavigation) {
369 scoped_ptr<Pickle> command_pickle(command->PayloadAsPickle());
370 PickleIterator iterator(*command_pickle);
371 SessionID::id_type command_tab_id;
372 int command_nav_index;
373 if (!command_pickle->ReadInt(&iterator, &command_tab_id) ||
374 !command_pickle->ReadInt(&iterator, &command_nav_index)) {
375 return false;
376 }
377 SessionID::id_type existing_tab_id;
378 int existing_nav_index;
379 {
380 // Creating a pickle like this means the Pickle references the data from
381 // the command. Make sure we delete the pickle before the command, else
382 // the pickle references deleted memory.
383 scoped_ptr<Pickle> existing_pickle(existing_command->PayloadAsPickle());
384 iterator = PickleIterator(*existing_pickle);
385 if (!existing_pickle->ReadInt(&iterator, &existing_tab_id) ||
386 !existing_pickle->ReadInt(&iterator, &existing_nav_index)) {
387 return false;
388 }
389 }
390 if (existing_tab_id == command_tab_id &&
391 existing_nav_index == command_nav_index) {
392 // existing_command is an update for the same tab/index pair. Replace
393 // it with the new one. We need to add to the end of the list just in
394 // case there is a prune command after the update command.
395 delete existing_command;
396 pending_commands.erase(i.base() - 1);
397 pending_commands.push_back(command);
398 return true;
399 }
400 return false;
401 }
402 if (command->id() == kCommandSetActiveWindow &&
403 existing_command->id() == kCommandSetActiveWindow) {
404 *i = command;
405 delete existing_command;
406 return true;
407 }
408 }
409 return false;
410 }
411
412 bool SessionServiceCommands::IsClosingCommand(SessionCommand* command) const {
413 return command->id() == kCommandTabClosed ||
414 command->id() == kCommandWindowClosed;
415 }
416
417 void SessionServiceCommands::RestoreSessionFromCommands(
418 const std::vector<SessionCommand*>& commands,
419 std::vector<SessionWindow*>* valid_windows,
420 SessionID::id_type* active_window_id) {
421 std::map<int, SessionTab*> tabs;
422 std::map<int, SessionWindow*> windows;
423
424 VLOG(1) << "RestoreSessionFromCommands " << commands.size();
425 if (CreateTabsAndWindows(commands, &tabs, &windows, active_window_id)) {
426 AddTabsToWindows(&tabs, &windows);
427 SortTabsBasedOnVisualOrderAndPrune(&windows, valid_windows);
428 UpdateSelectedTabIndex(valid_windows);
429 }
430 STLDeleteValues(&tabs);
431 // Don't delete contents of windows, that is done by the caller as all
432 // valid windows are added to valid_windows.
433 }
434
435 void SessionServiceCommands::UpdateSelectedTabIndex(
436 std::vector<SessionWindow*>* windows) {
437 for (std::vector<SessionWindow*>::const_iterator i = windows->begin();
438 i != windows->end(); ++i) {
439 // See note in SessionWindow as to why we do this.
440 int new_index = 0;
441 for (std::vector<SessionTab*>::const_iterator j = (*i)->tabs.begin();
442 j != (*i)->tabs.end(); ++j) {
443 if ((*j)->tab_visual_index == (*i)->selected_tab_index) {
444 new_index = static_cast<int>(j - (*i)->tabs.begin());
445 break;
446 }
447 }
448 (*i)->selected_tab_index = new_index;
449 }
450 }
451
452 SessionWindow* SessionServiceCommands::GetWindow(SessionID::id_type window_id,
453 IdToSessionWindow* windows) {
454 std::map<int, SessionWindow*>::iterator i = windows->find(window_id);
455 if (i == windows->end()) {
456 SessionWindow* window = new SessionWindow();
457 window->window_id.set_id(window_id);
458 (*windows)[window_id] = window;
459 return window;
460 }
461 return i->second;
462 }
463
464 SessionTab* SessionServiceCommands::GetTab(SessionID::id_type tab_id,
465 IdToSessionTab* tabs) {
466 DCHECK(tabs);
467 std::map<int, SessionTab*>::iterator i = tabs->find(tab_id);
468 if (i == tabs->end()) {
469 SessionTab* tab = new SessionTab();
470 tab->tab_id.set_id(tab_id);
471 (*tabs)[tab_id] = tab;
472 return tab;
473 }
474 return i->second;
475 }
476
477 std::vector<sessions::SerializedNavigationEntry>::iterator
478 SessionServiceCommands::FindClosestNavigationWithIndex(
479 std::vector<sessions::SerializedNavigationEntry>* navigations,
480 int index) {
481 DCHECK(navigations);
482 for (std::vector<sessions::SerializedNavigationEntry>::iterator
483 i = navigations->begin(); i != navigations->end(); ++i) {
484 if (i->index() >= index)
485 return i;
486 }
487 return navigations->end();
488 }
489
490 // Function used in sorting windows. Sorting is done based on window id. As
491 // window ids increment for each new window, this effectively sorts by creation
492 // time.
493 static bool WindowOrderSortFunction(const SessionWindow* w1,
494 const SessionWindow* w2) {
495 return w1->window_id.id() < w2->window_id.id();
496 }
497
498 // Compares the two tabs based on visual index.
499 static bool TabVisualIndexSortFunction(const SessionTab* t1,
500 const SessionTab* t2) {
501 const int delta = t1->tab_visual_index - t2->tab_visual_index;
502 return delta == 0 ? (t1->tab_id.id() < t2->tab_id.id()) : (delta < 0);
503 }
504
505 void SessionServiceCommands::SortTabsBasedOnVisualOrderAndPrune(
506 std::map<int, SessionWindow*>* windows,
507 std::vector<SessionWindow*>* valid_windows) {
508 std::map<int, SessionWindow*>::iterator i = windows->begin();
509 while (i != windows->end()) {
510 SessionWindow* window = i->second;
511 AppType app_type = window->app_name.empty() ? TYPE_NORMAL : TYPE_APP;
512 if (window->tabs.empty() || window->is_constrained ||
513 !ShouldRestoreWindowOfType(window->type, app_type)) {
514 delete window;
515 windows->erase(i++);
516 } else {
517 // Valid window; sort the tabs and add it to the list of valid windows.
518 std::sort(window->tabs.begin(), window->tabs.end(),
519 &TabVisualIndexSortFunction);
520 // Otherwise, add the window such that older windows appear first.
521 if (valid_windows->empty()) {
522 valid_windows->push_back(window);
523 } else {
524 valid_windows->insert(
525 std::upper_bound(valid_windows->begin(), valid_windows->end(),
526 window, &WindowOrderSortFunction),
527 window);
528 }
529 ++i;
530 }
531 }
532 }
533
534 void SessionServiceCommands::AddTabsToWindows(std::map<int, SessionTab*>* tabs,
535 std::map<int, SessionWindow*>* windows) {
536 VLOG(1) << "AddTabsToWindws";
537 VLOG(1) << "Tabs " << tabs->size() << ", windows " << windows->size();
538 std::map<int, SessionTab*>::iterator i = tabs->begin();
539 while (i != tabs->end()) {
540 SessionTab* tab = i->second;
541 if (tab->window_id.id() && !tab->navigations.empty()) {
542 SessionWindow* window = GetWindow(tab->window_id.id(), windows);
543 window->tabs.push_back(tab);
544 tabs->erase(i++);
545
546 // See note in SessionTab as to why we do this.
547 std::vector<sessions::SerializedNavigationEntry>::iterator j =
548 FindClosestNavigationWithIndex(&(tab->navigations),
549 tab->current_navigation_index);
550 if (j == tab->navigations.end()) {
551 tab->current_navigation_index =
552 static_cast<int>(tab->navigations.size() - 1);
553 } else {
554 tab->current_navigation_index =
555 static_cast<int>(j - tab->navigations.begin());
556 }
557 } else {
558 // Never got a set tab index in window, or tabs are empty, nothing
559 // to do.
560 ++i;
561 }
562 }
563 }
564
565 bool SessionServiceCommands::CreateTabsAndWindows(
566 const std::vector<SessionCommand*>& data,
567 std::map<int, SessionTab*>* tabs,
568 std::map<int, SessionWindow*>* windows,
569 SessionID::id_type* active_window_id) {
570 // If the file is corrupt (command with wrong size, or unknown command), we
571 // still return true and attempt to restore what we we can.
572 VLOG(1) << "CreateTabsAndWindows";
573
574 for (std::vector<SessionCommand*>::const_iterator i = data.begin();
575 i != data.end(); ++i) {
576 const SessionCommand::id_type kCommandSetWindowBounds2 = 10;
577 const SessionCommand* command = *i;
578
579 VLOG(1) << "Read command " << (int) command->id();
580 switch (command->id()) {
581 case kCommandSetTabWindow: {
582 SessionID::id_type payload[2];
583 if (!command->GetPayload(payload, sizeof(payload))) {
584 VLOG(1) << "Failed reading command " << command->id();
585 return true;
586 }
587 GetTab(payload[1], tabs)->window_id.set_id(payload[0]);
588 break;
589 }
590
591 // This is here for forward migration only. New data is saved with
592 // |kCommandSetWindowBounds3|.
593 case kCommandSetWindowBounds2: {
594 WindowBoundsPayload2 payload;
595 if (!command->GetPayload(&payload, sizeof(payload))) {
596 VLOG(1) << "Failed reading command " << command->id();
597 return true;
598 }
599 GetWindow(payload.window_id, windows)->bounds.SetRect(payload.x,
600 payload.y,
601 payload.w,
602 payload.h);
603 GetWindow(payload.window_id, windows)->show_state =
604 payload.is_maximized ?
605 ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL;
606 break;
607 }
608
609 case kCommandSetWindowBounds3: {
610 WindowBoundsPayload3 payload;
611 if (!command->GetPayload(&payload, sizeof(payload))) {
612 VLOG(1) << "Failed reading command " << command->id();
613 return true;
614 }
615 GetWindow(payload.window_id, windows)->bounds.SetRect(payload.x,
616 payload.y,
617 payload.w,
618 payload.h);
619 GetWindow(payload.window_id, windows)->show_state =
620 PersistedShowStateToShowState(payload.show_state);
621 break;
622 }
623
624 case kCommandSetTabIndexInWindow: {
625 TabIndexInWindowPayload payload;
626 if (!command->GetPayload(&payload, sizeof(payload))) {
627 VLOG(1) << "Failed reading command " << command->id();
628 return true;
629 }
630 GetTab(payload.id, tabs)->tab_visual_index = payload.index;
631 break;
632 }
633
634 case kCommandTabClosed:
635 case kCommandWindowClosed: {
636 ClosedPayload payload;
637 if (!command->GetPayload(&payload, sizeof(payload))) {
638 VLOG(1) << "Failed reading command " << command->id();
639 return true;
640 }
641 if (command->id() == kCommandTabClosed) {
642 delete GetTab(payload.id, tabs);
643 tabs->erase(payload.id);
644 } else {
645 delete GetWindow(payload.id, windows);
646 windows->erase(payload.id);
647 }
648 break;
649 }
650
651 case kCommandTabNavigationPathPrunedFromBack: {
652 TabNavigationPathPrunedFromBackPayload payload;
653 if (!command->GetPayload(&payload, sizeof(payload))) {
654 VLOG(1) << "Failed reading command " << command->id();
655 return true;
656 }
657 SessionTab* tab = GetTab(payload.id, tabs);
658 tab->navigations.erase(
659 FindClosestNavigationWithIndex(&(tab->navigations), payload.index),
660 tab->navigations.end());
661 break;
662 }
663
664 case kCommandTabNavigationPathPrunedFromFront: {
665 TabNavigationPathPrunedFromFrontPayload payload;
666 if (!command->GetPayload(&payload, sizeof(payload)) ||
667 payload.index <= 0) {
668 VLOG(1) << "Failed reading command " << command->id();
669 return true;
670 }
671 SessionTab* tab = GetTab(payload.id, tabs);
672
673 // Update the selected navigation index.
674 tab->current_navigation_index =
675 std::max(-1, tab->current_navigation_index - payload.index);
676
677 // And update the index of existing navigations.
678 for (std::vector<sessions::SerializedNavigationEntry>::iterator
679 i = tab->navigations.begin();
680 i != tab->navigations.end();) {
681 i->set_index(i->index() - payload.index);
682 if (i->index() < 0)
683 i = tab->navigations.erase(i);
684 else
685 ++i;
686 }
687 break;
688 }
689
690 case kCommandUpdateTabNavigation: {
691 sessions::SerializedNavigationEntry navigation;
692 SessionID::id_type tab_id;
693 if (!RestoreUpdateTabNavigationCommand(*command,
694 &navigation,
695 &tab_id)) {
696 VLOG(1) << "Failed reading command " << command->id();
697 return true;
698 }
699 SessionTab* tab = GetTab(tab_id, tabs);
700 std::vector<sessions::SerializedNavigationEntry>::iterator i =
701 FindClosestNavigationWithIndex(&(tab->navigations),
702 navigation.index());
703 if (i != tab->navigations.end() && i->index() == navigation.index())
704 *i = navigation;
705 else
706 tab->navigations.insert(i, navigation);
707 break;
708 }
709
710 case kCommandSetSelectedNavigationIndex: {
711 SelectedNavigationIndexPayload payload;
712 if (!command->GetPayload(&payload, sizeof(payload))) {
713 VLOG(1) << "Failed reading command " << command->id();
714 return true;
715 }
716 GetTab(payload.id, tabs)->current_navigation_index = payload.index;
717 break;
718 }
719
720 case kCommandSetSelectedTabInIndex: {
721 SelectedTabInIndexPayload payload;
722 if (!command->GetPayload(&payload, sizeof(payload))) {
723 VLOG(1) << "Failed reading command " << command->id();
724 return true;
725 }
726 GetWindow(payload.id, windows)->selected_tab_index = payload.index;
727 break;
728 }
729
730 case kCommandSetWindowType: {
731 WindowTypePayload payload;
732 if (!command->GetPayload(&payload, sizeof(payload))) {
733 VLOG(1) << "Failed reading command " << command->id();
734 return true;
735 }
736 GetWindow(payload.id, windows)->is_constrained = false;
737 GetWindow(payload.id, windows)->type =
738 static_cast<SessionWindow::WindowType>(payload.index);
739 break;
740 }
741
742 case kCommandSetPinnedState: {
743 PinnedStatePayload payload;
744 if (!command->GetPayload(&payload, sizeof(payload))) {
745 VLOG(1) << "Failed reading command " << command->id();
746 return true;
747 }
748 GetTab(payload.tab_id, tabs)->pinned = payload.pinned_state;
749 break;
750 }
751
752 case kCommandSetWindowAppName: {
753 SessionID::id_type window_id;
754 std::string app_name;
755 if (!RestoreSetWindowAppNameCommand(*command, &window_id, &app_name))
756 return true;
757
758 GetWindow(window_id, windows)->app_name.swap(app_name);
759 break;
760 }
761
762 case kCommandSetExtensionAppID: {
763 SessionID::id_type tab_id;
764 std::string extension_app_id;
765 if (!RestoreSetTabExtensionAppIDCommand(*command,
766 &tab_id,
767 &extension_app_id)) {
768 VLOG(1) << "Failed reading command " << command->id();
769 return true;
770 }
771
772 GetTab(tab_id, tabs)->extension_app_id.swap(extension_app_id);
773 break;
774 }
775
776 case kCommandSetTabUserAgentOverride: {
777 SessionID::id_type tab_id;
778 std::string user_agent_override;
779 if (!RestoreSetTabUserAgentOverrideCommand(
780 *command,
781 &tab_id,
782 &user_agent_override)) {
783 return true;
784 }
785
786 GetTab(tab_id, tabs)->user_agent_override.swap(user_agent_override);
787 break;
788 }
789
790 case kCommandSessionStorageAssociated: {
791 scoped_ptr<Pickle> command_pickle(command->PayloadAsPickle());
792 SessionID::id_type command_tab_id;
793 std::string session_storage_persistent_id;
794 PickleIterator iter(*command_pickle.get());
795 if (!command_pickle->ReadInt(&iter, &command_tab_id) ||
796 !command_pickle->ReadString(&iter, &session_storage_persistent_id))
797 return true;
798 // Associate the session storage back.
799 GetTab(command_tab_id, tabs)->session_storage_persistent_id =
800 session_storage_persistent_id;
801 break;
802 }
803
804 case kCommandSetActiveWindow: {
805 ActiveWindowPayload payload;
806 if (!command->GetPayload(&payload, sizeof(payload))) {
807 VLOG(1) << "Failed reading command " << command->id();
808 return true;
809 }
810 *active_window_id = payload;
811 break;
812 }
813
814 default:
815 // TODO(skuhne): This might call back into a callback handler to extend
816 // the command set for specific implementations.
817 VLOG(1) << "Failed reading an unknown command " << command->id();
818 return true;
819 }
820 }
821 return true;
822 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698