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

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: Switched back to #2 and addressed points 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 // TODO(skuhne): Check why this command needs to be called from the base.
327 // thus: could eliminate the use of that class here.
328 return ::CreateUpdateTabNavigationCommand(kCommandUpdateTabNavigation,
329 tab_id.id(),
330 navigation);
331 }
332
333 SessionCommand* SessionServiceCommands::CreateSetTabExtensionAppIDCommand(
334 const SessionID& tab_id,
335 const std::string& extension_id) {
336 return ::CreateSetTabExtensionAppIDCommand(kCommandSetExtensionAppID,
337 tab_id.id(),
338 extension_id);
339 }
340
341 SessionCommand* SessionServiceCommands::CreateSetTabUserAgentOverrideCommand(
342 const SessionID& tab_id,
343 const std::string& user_agent_override) {
344 return ::CreateSetTabUserAgentOverrideCommand(kCommandSetTabUserAgentOverride,
345 tab_id.id(),
346 user_agent_override);
347 }
348
349 SessionCommand* SessionServiceCommands::CreateSetWindowAppNameCommand(
350 const SessionID& window_id,
351 const std::string& app_name) {
352 return ::CreateSetWindowAppNameCommand(kCommandSetWindowAppName,
353 window_id.id(),
354 app_name);
355 }
356
357 bool SessionServiceCommands::ReplacePendingCommand(
358 SessionCommand* command,
359 std::vector<SessionCommand*>& pending_commands) {
360 // We optimize page navigations, which can happen quite frequently and
361 // is expensive. And activation is like Highlander, there can only be one!
362 if (command->id() != kCommandUpdateTabNavigation &&
363 command->id() != kCommandSetActiveWindow) {
364 return false;
365 }
366 for (std::vector<SessionCommand*>::reverse_iterator i =
367 pending_commands.rbegin(); i != pending_commands.rend(); ++i) {
368 SessionCommand* existing_command = *i;
369 if (command->id() == kCommandUpdateTabNavigation &&
370 existing_command->id() == kCommandUpdateTabNavigation) {
371 scoped_ptr<Pickle> command_pickle(command->PayloadAsPickle());
372 PickleIterator iterator(*command_pickle);
373 SessionID::id_type command_tab_id;
374 int command_nav_index;
375 if (!command_pickle->ReadInt(&iterator, &command_tab_id) ||
376 !command_pickle->ReadInt(&iterator, &command_nav_index)) {
377 return false;
378 }
379 SessionID::id_type existing_tab_id;
380 int existing_nav_index;
381 {
382 // Creating a pickle like this means the Pickle references the data from
383 // the command. Make sure we delete the pickle before the command, else
384 // the pickle references deleted memory.
385 scoped_ptr<Pickle> existing_pickle(existing_command->PayloadAsPickle());
386 iterator = PickleIterator(*existing_pickle);
387 if (!existing_pickle->ReadInt(&iterator, &existing_tab_id) ||
388 !existing_pickle->ReadInt(&iterator, &existing_nav_index)) {
389 return false;
390 }
391 }
392 if (existing_tab_id == command_tab_id &&
393 existing_nav_index == command_nav_index) {
394 // existing_command is an update for the same tab/index pair. Replace
395 // it with the new one. We need to add to the end of the list just in
396 // case there is a prune command after the update command.
397 delete existing_command;
398 pending_commands.erase(i.base() - 1);
399 pending_commands.push_back(command);
400 return true;
401 }
402 return false;
403 }
404 if (command->id() == kCommandSetActiveWindow &&
405 existing_command->id() == kCommandSetActiveWindow) {
406 *i = command;
407 delete existing_command;
408 return true;
409 }
410 }
411 return false;
412 }
413
414 bool SessionServiceCommands::IsClosingCommand(SessionCommand* command) const {
415 return command->id() == kCommandTabClosed ||
416 command->id() == kCommandWindowClosed;
417 }
418
419 void SessionServiceCommands::RestoreSessionFromCommands(
420 const std::vector<SessionCommand*>& commands,
421 std::vector<SessionWindow*>* valid_windows,
422 SessionID::id_type* active_window_id) {
423 std::map<int, SessionTab*> tabs;
424 std::map<int, SessionWindow*> windows;
425
426 VLOG(1) << "RestoreSessionFromCommands " << commands.size();
427 if (CreateTabsAndWindows(commands, &tabs, &windows, active_window_id)) {
428 AddTabsToWindows(&tabs, &windows);
429 SortTabsBasedOnVisualOrderAndPrune(&windows, valid_windows);
430 UpdateSelectedTabIndex(valid_windows);
431 }
432 STLDeleteValues(&tabs);
433 // Don't delete contents of windows, that is done by the caller as all
434 // valid windows are added to valid_windows.
435 }
436
437 void SessionServiceCommands::UpdateSelectedTabIndex(
438 std::vector<SessionWindow*>* windows) {
439 for (std::vector<SessionWindow*>::const_iterator i = windows->begin();
440 i != windows->end(); ++i) {
441 // See note in SessionWindow as to why we do this.
442 int new_index = 0;
443 for (std::vector<SessionTab*>::const_iterator j = (*i)->tabs.begin();
444 j != (*i)->tabs.end(); ++j) {
445 if ((*j)->tab_visual_index == (*i)->selected_tab_index) {
446 new_index = static_cast<int>(j - (*i)->tabs.begin());
447 break;
448 }
449 }
450 (*i)->selected_tab_index = new_index;
451 }
452 }
453
454 SessionWindow* SessionServiceCommands::GetWindow(SessionID::id_type window_id,
455 IdToSessionWindow* windows) {
456 std::map<int, SessionWindow*>::iterator i = windows->find(window_id);
457 if (i == windows->end()) {
458 SessionWindow* window = new SessionWindow();
459 window->window_id.set_id(window_id);
460 (*windows)[window_id] = window;
461 return window;
462 }
463 return i->second;
464 }
465
466 SessionTab* SessionServiceCommands::GetTab(SessionID::id_type tab_id,
467 IdToSessionTab* tabs) {
468 DCHECK(tabs);
469 std::map<int, SessionTab*>::iterator i = tabs->find(tab_id);
470 if (i == tabs->end()) {
471 SessionTab* tab = new SessionTab();
472 tab->tab_id.set_id(tab_id);
473 (*tabs)[tab_id] = tab;
474 return tab;
475 }
476 return i->second;
477 }
478
479 std::vector<sessions::SerializedNavigationEntry>::iterator
480 SessionServiceCommands::FindClosestNavigationWithIndex(
481 std::vector<sessions::SerializedNavigationEntry>* navigations,
482 int index) {
483 DCHECK(navigations);
484 for (std::vector<sessions::SerializedNavigationEntry>::iterator
485 i = navigations->begin(); i != navigations->end(); ++i) {
486 if (i->index() >= index)
487 return i;
488 }
489 return navigations->end();
490 }
491
492 // Function used in sorting windows. Sorting is done based on window id. As
493 // window ids increment for each new window, this effectively sorts by creation
494 // time.
495 static bool WindowOrderSortFunction(const SessionWindow* w1,
496 const SessionWindow* w2) {
497 return w1->window_id.id() < w2->window_id.id();
498 }
499
500 // Compares the two tabs based on visual index.
501 static bool TabVisualIndexSortFunction(const SessionTab* t1,
502 const SessionTab* t2) {
503 const int delta = t1->tab_visual_index - t2->tab_visual_index;
504 return delta == 0 ? (t1->tab_id.id() < t2->tab_id.id()) : (delta < 0);
505 }
506
507 void SessionServiceCommands::SortTabsBasedOnVisualOrderAndPrune(
508 std::map<int, SessionWindow*>* windows,
509 std::vector<SessionWindow*>* valid_windows) {
510 std::map<int, SessionWindow*>::iterator i = windows->begin();
511 while (i != windows->end()) {
512 SessionWindow* window = i->second;
513 AppType app_type = window->app_name.empty() ? TYPE_NORMAL : TYPE_APP;
514 if (window->tabs.empty() || window->is_constrained ||
515 !ShouldRestoreWindowOfType(window->type, app_type)) {
516 delete window;
517 windows->erase(i++);
518 } else {
519 // Valid window; sort the tabs and add it to the list of valid windows.
520 std::sort(window->tabs.begin(), window->tabs.end(),
521 &TabVisualIndexSortFunction);
522 // Otherwise, add the window such that older windows appear first.
523 if (valid_windows->empty()) {
524 valid_windows->push_back(window);
525 } else {
526 valid_windows->insert(
527 std::upper_bound(valid_windows->begin(), valid_windows->end(),
528 window, &WindowOrderSortFunction),
529 window);
530 }
531 ++i;
532 }
533 }
534 }
535
536 void SessionServiceCommands::AddTabsToWindows(std::map<int, SessionTab*>* tabs,
537 std::map<int, SessionWindow*>* windows) {
538 VLOG(1) << "AddTabsToWindws";
539 VLOG(1) << "Tabs " << tabs->size() << ", windows " << windows->size();
540 std::map<int, SessionTab*>::iterator i = tabs->begin();
541 while (i != tabs->end()) {
542 SessionTab* tab = i->second;
543 if (tab->window_id.id() && !tab->navigations.empty()) {
544 SessionWindow* window = GetWindow(tab->window_id.id(), windows);
545 window->tabs.push_back(tab);
546 tabs->erase(i++);
547
548 // See note in SessionTab as to why we do this.
549 std::vector<sessions::SerializedNavigationEntry>::iterator j =
550 FindClosestNavigationWithIndex(&(tab->navigations),
551 tab->current_navigation_index);
552 if (j == tab->navigations.end()) {
553 tab->current_navigation_index =
554 static_cast<int>(tab->navigations.size() - 1);
555 } else {
556 tab->current_navigation_index =
557 static_cast<int>(j - tab->navigations.begin());
558 }
559 } else {
560 // Never got a set tab index in window, or tabs are empty, nothing
561 // to do.
562 ++i;
563 }
564 }
565 }
566
567 bool SessionServiceCommands::CreateTabsAndWindows(
568 const std::vector<SessionCommand*>& data,
569 std::map<int, SessionTab*>* tabs,
570 std::map<int, SessionWindow*>* windows,
571 SessionID::id_type* active_window_id) {
572 // If the file is corrupt (command with wrong size, or unknown command), we
573 // still return true and attempt to restore what we we can.
574 VLOG(1) << "CreateTabsAndWindows";
575
576 for (std::vector<SessionCommand*>::const_iterator i = data.begin();
577 i != data.end(); ++i) {
578 const SessionCommand::id_type kCommandSetWindowBounds2 = 10;
579 const SessionCommand* command = *i;
580
581 VLOG(1) << "Read command " << (int) command->id();
582 switch (command->id()) {
583 case kCommandSetTabWindow: {
584 SessionID::id_type payload[2];
585 if (!command->GetPayload(payload, sizeof(payload))) {
586 VLOG(1) << "Failed reading command " << command->id();
587 return true;
588 }
589 GetTab(payload[1], tabs)->window_id.set_id(payload[0]);
590 break;
591 }
592
593 // This is here for forward migration only. New data is saved with
594 // |kCommandSetWindowBounds3|.
595 case kCommandSetWindowBounds2: {
596 WindowBoundsPayload2 payload;
597 if (!command->GetPayload(&payload, sizeof(payload))) {
598 VLOG(1) << "Failed reading command " << command->id();
599 return true;
600 }
601 GetWindow(payload.window_id, windows)->bounds.SetRect(payload.x,
602 payload.y,
603 payload.w,
604 payload.h);
605 GetWindow(payload.window_id, windows)->show_state =
606 payload.is_maximized ?
607 ui::SHOW_STATE_MAXIMIZED : ui::SHOW_STATE_NORMAL;
608 break;
609 }
610
611 case kCommandSetWindowBounds3: {
612 WindowBoundsPayload3 payload;
613 if (!command->GetPayload(&payload, sizeof(payload))) {
614 VLOG(1) << "Failed reading command " << command->id();
615 return true;
616 }
617 GetWindow(payload.window_id, windows)->bounds.SetRect(payload.x,
618 payload.y,
619 payload.w,
620 payload.h);
621 GetWindow(payload.window_id, windows)->show_state =
622 PersistedShowStateToShowState(payload.show_state);
623 break;
624 }
625
626 case kCommandSetTabIndexInWindow: {
627 TabIndexInWindowPayload payload;
628 if (!command->GetPayload(&payload, sizeof(payload))) {
629 VLOG(1) << "Failed reading command " << command->id();
630 return true;
631 }
632 GetTab(payload.id, tabs)->tab_visual_index = payload.index;
633 break;
634 }
635
636 case kCommandTabClosed:
637 case kCommandWindowClosed: {
638 ClosedPayload payload;
639 if (!command->GetPayload(&payload, sizeof(payload))) {
640 VLOG(1) << "Failed reading command " << command->id();
641 return true;
642 }
643 if (command->id() == kCommandTabClosed) {
644 delete GetTab(payload.id, tabs);
645 tabs->erase(payload.id);
646 } else {
647 delete GetWindow(payload.id, windows);
648 windows->erase(payload.id);
649 }
650 break;
651 }
652
653 case kCommandTabNavigationPathPrunedFromBack: {
654 TabNavigationPathPrunedFromBackPayload payload;
655 if (!command->GetPayload(&payload, sizeof(payload))) {
656 VLOG(1) << "Failed reading command " << command->id();
657 return true;
658 }
659 SessionTab* tab = GetTab(payload.id, tabs);
660 tab->navigations.erase(
661 FindClosestNavigationWithIndex(&(tab->navigations), payload.index),
662 tab->navigations.end());
663 break;
664 }
665
666 case kCommandTabNavigationPathPrunedFromFront: {
667 TabNavigationPathPrunedFromFrontPayload payload;
668 if (!command->GetPayload(&payload, sizeof(payload)) ||
669 payload.index <= 0) {
670 VLOG(1) << "Failed reading command " << command->id();
671 return true;
672 }
673 SessionTab* tab = GetTab(payload.id, tabs);
674
675 // Update the selected navigation index.
676 tab->current_navigation_index =
677 std::max(-1, tab->current_navigation_index - payload.index);
678
679 // And update the index of existing navigations.
680 for (std::vector<sessions::SerializedNavigationEntry>::iterator
681 i = tab->navigations.begin();
682 i != tab->navigations.end();) {
683 i->set_index(i->index() - payload.index);
684 if (i->index() < 0)
685 i = tab->navigations.erase(i);
686 else
687 ++i;
688 }
689 break;
690 }
691
692 case kCommandUpdateTabNavigation: {
693 sessions::SerializedNavigationEntry navigation;
694 SessionID::id_type tab_id;
695 if (!RestoreUpdateTabNavigationCommand(*command,
696 &navigation,
697 &tab_id)) {
698 VLOG(1) << "Failed reading command " << command->id();
699 return true;
700 }
701 SessionTab* tab = GetTab(tab_id, tabs);
702 std::vector<sessions::SerializedNavigationEntry>::iterator i =
703 FindClosestNavigationWithIndex(&(tab->navigations),
704 navigation.index());
705 if (i != tab->navigations.end() && i->index() == navigation.index())
706 *i = navigation;
707 else
708 tab->navigations.insert(i, navigation);
709 break;
710 }
711
712 case kCommandSetSelectedNavigationIndex: {
713 SelectedNavigationIndexPayload payload;
714 if (!command->GetPayload(&payload, sizeof(payload))) {
715 VLOG(1) << "Failed reading command " << command->id();
716 return true;
717 }
718 GetTab(payload.id, tabs)->current_navigation_index = payload.index;
719 break;
720 }
721
722 case kCommandSetSelectedTabInIndex: {
723 SelectedTabInIndexPayload payload;
724 if (!command->GetPayload(&payload, sizeof(payload))) {
725 VLOG(1) << "Failed reading command " << command->id();
726 return true;
727 }
728 GetWindow(payload.id, windows)->selected_tab_index = payload.index;
729 break;
730 }
731
732 case kCommandSetWindowType: {
733 WindowTypePayload payload;
734 if (!command->GetPayload(&payload, sizeof(payload))) {
735 VLOG(1) << "Failed reading command " << command->id();
736 return true;
737 }
738 GetWindow(payload.id, windows)->is_constrained = false;
739 GetWindow(payload.id, windows)->type =
740 static_cast<SessionWindow::WindowType>(payload.index);
741 break;
742 }
743
744 case kCommandSetPinnedState: {
745 PinnedStatePayload payload;
746 if (!command->GetPayload(&payload, sizeof(payload))) {
747 VLOG(1) << "Failed reading command " << command->id();
748 return true;
749 }
750 GetTab(payload.tab_id, tabs)->pinned = payload.pinned_state;
751 break;
752 }
753
754 case kCommandSetWindowAppName: {
755 SessionID::id_type window_id;
756 std::string app_name;
757 if (!RestoreSetWindowAppNameCommand(*command, &window_id, &app_name))
758 return true;
759
760 GetWindow(window_id, windows)->app_name.swap(app_name);
761 break;
762 }
763
764 case kCommandSetExtensionAppID: {
765 SessionID::id_type tab_id;
766 std::string extension_app_id;
767 if (!RestoreSetTabExtensionAppIDCommand(*command,
768 &tab_id,
769 &extension_app_id)) {
770 VLOG(1) << "Failed reading command " << command->id();
771 return true;
772 }
773
774 GetTab(tab_id, tabs)->extension_app_id.swap(extension_app_id);
775 break;
776 }
777
778 case kCommandSetTabUserAgentOverride: {
779 SessionID::id_type tab_id;
780 std::string user_agent_override;
781 if (!RestoreSetTabUserAgentOverrideCommand(
782 *command,
783 &tab_id,
784 &user_agent_override)) {
785 return true;
786 }
787
788 GetTab(tab_id, tabs)->user_agent_override.swap(user_agent_override);
789 break;
790 }
791
792 case kCommandSessionStorageAssociated: {
793 scoped_ptr<Pickle> command_pickle(command->PayloadAsPickle());
794 SessionID::id_type command_tab_id;
795 std::string session_storage_persistent_id;
796 PickleIterator iter(*command_pickle.get());
797 if (!command_pickle->ReadInt(&iter, &command_tab_id) ||
798 !command_pickle->ReadString(&iter, &session_storage_persistent_id))
799 return true;
800 // Associate the session storage back.
801 GetTab(command_tab_id, tabs)->session_storage_persistent_id =
802 session_storage_persistent_id;
803 break;
804 }
805
806 case kCommandSetActiveWindow: {
807 ActiveWindowPayload payload;
808 if (!command->GetPayload(&payload, sizeof(payload))) {
809 VLOG(1) << "Failed reading command " << command->id();
810 return true;
811 }
812 *active_window_id = payload;
813 break;
814 }
815
816 default:
817 // TODO(skuhne): This might call back into a callback handler to extend
818 // the command set for specific implementations.
819 VLOG(1) << "Failed reading an unknown command " << command->id();
820 return true;
821 }
822 }
823 return true;
824 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698