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

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

Powered by Google App Engine
This is Rietveld 408576698