OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "base/bind.h" | 5 #include "base/bind.h" |
6 #include "base/bind_helpers.h" | 6 #include "base/bind_helpers.h" |
7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
8 #include "base/files/scoped_temp_dir.h" | 8 #include "base/files/scoped_temp_dir.h" |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "base/memory/scoped_vector.h" | 10 #include "base/memory/scoped_vector.h" |
11 #include "base/path_service.h" | 11 #include "base/path_service.h" |
| 12 #include "base/run_loop.h" |
12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
13 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
14 #include "base/strings/utf_string_conversions.h" | 15 #include "base/strings/utf_string_conversions.h" |
| 16 #include "base/synchronization/waitable_event.h" |
15 #include "base/time/time.h" | 17 #include "base/time/time.h" |
16 #include "chrome/browser/browser_process.h" | 18 #include "chrome/browser/browser_process.h" |
17 #include "chrome/browser/chrome_notification_types.h" | 19 #include "chrome/browser/chrome_notification_types.h" |
18 #include "chrome/browser/defaults.h" | 20 #include "chrome/browser/defaults.h" |
19 #include "chrome/browser/profiles/profile_manager.h" | 21 #include "chrome/browser/profiles/profile_manager.h" |
20 #include "chrome/browser/sessions/session_backend.h" | 22 #include "chrome/browser/sessions/session_backend.h" |
21 #include "chrome/browser/sessions/session_service.h" | 23 #include "chrome/browser/sessions/session_service.h" |
22 #include "chrome/browser/sessions/session_service_test_helper.h" | 24 #include "chrome/browser/sessions/session_service_test_helper.h" |
23 #include "chrome/browser/sessions/session_types.h" | 25 #include "chrome/browser/sessions/session_types.h" |
24 #include "chrome/common/chrome_paths.h" | 26 #include "chrome/common/chrome_paths.h" |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 window2_id, Browser::TYPE_TABBED, SessionService::TYPE_NORMAL); | 159 window2_id, Browser::TYPE_TABBED, SessionService::TYPE_NORMAL); |
158 service()->SetWindowBounds(window2_id, | 160 service()->SetWindowBounds(window2_id, |
159 window2_bounds, | 161 window2_bounds, |
160 ui::SHOW_STATE_MAXIMIZED); | 162 ui::SHOW_STATE_MAXIMIZED); |
161 helper_.PrepareTabInWindow(window2_id, tab2_id, 0, true); | 163 helper_.PrepareTabInWindow(window2_id, tab2_id, 0, true); |
162 UpdateNavigation(window2_id, tab2_id, *nav2, true); | 164 UpdateNavigation(window2_id, tab2_id, *nav2, true); |
163 } | 165 } |
164 | 166 |
165 SessionService* service() { return helper_.service(); } | 167 SessionService* service() { return helper_.service(); } |
166 | 168 |
167 SessionBackend* backend() { return helper_.backend(); } | |
168 | |
169 const gfx::Rect window_bounds; | 169 const gfx::Rect window_bounds; |
170 | 170 |
171 SessionID window_id; | 171 SessionID window_id; |
172 | 172 |
173 int sync_save_count_; | 173 int sync_save_count_; |
174 | 174 |
175 // Path used in testing. | 175 // Path used in testing. |
176 base::ScopedTempDir temp_dir_; | 176 base::ScopedTempDir temp_dir_; |
177 base::FilePath path_; | 177 base::FilePath path_; |
178 | 178 |
(...skipping 813 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
992 | 992 |
993 ASSERT_EQ(1U, windows.size()); | 993 ASSERT_EQ(1U, windows.size()); |
994 ASSERT_EQ(0, windows[0]->selected_tab_index); | 994 ASSERT_EQ(0, windows[0]->selected_tab_index); |
995 ASSERT_EQ(window_id.id(), windows[0]->window_id.id()); | 995 ASSERT_EQ(window_id.id(), windows[0]->window_id.id()); |
996 ASSERT_EQ(1U, windows[0]->tabs.size()); | 996 ASSERT_EQ(1U, windows[0]->tabs.size()); |
997 | 997 |
998 SessionTab* tab = windows[0]->tabs[0]; | 998 SessionTab* tab = windows[0]->tabs[0]; |
999 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab); | 999 helper_.AssertTabEquals(window_id, tab_id, 0, 0, 1, *tab); |
1000 helper_.AssertNavigationEquals(nav1, tab->navigations[0]); | 1000 helper_.AssertNavigationEquals(nav1, tab->navigations[0]); |
1001 } | 1001 } |
| 1002 |
| 1003 // Functions used by GetSessionsAndDestroy. |
| 1004 namespace { |
| 1005 |
| 1006 void OnGotPreviousSession(ScopedVector<SessionWindow> windows, |
| 1007 SessionID::id_type ignored_active_window) { |
| 1008 FAIL() << "SessionService was destroyed, this shouldn't be reached."; |
| 1009 } |
| 1010 |
| 1011 void PostBackToThread(base::MessageLoop* message_loop, |
| 1012 base::RunLoop* run_loop) { |
| 1013 message_loop->PostTask(FROM_HERE, |
| 1014 base::Bind(&base::RunLoop::Quit, |
| 1015 base::Unretained(run_loop))); |
| 1016 } |
| 1017 |
| 1018 } // namespace |
| 1019 |
| 1020 // Verifies that SessionService::GetLastSession() works correctly if the |
| 1021 // SessionService is deleted during processing. To verify the problematic case |
| 1022 // does the following: |
| 1023 // 1. Sends a task to the background thread that blocks. |
| 1024 // 2. Asks SessionService for the last session commands. This is blocked by 1. |
| 1025 // 3. Posts another task to the background thread, this too is blocked by 1. |
| 1026 // 4. Deletes SessionService. |
| 1027 // 5. Signals the semaphore that 2 and 3 are waiting on, allowing |
| 1028 // GetLastSession() to continue. |
| 1029 // 6. runs the message loop, this is quit when the task scheduled in 3 posts |
| 1030 // back to the ui thread to quit the run loop. |
| 1031 // The call to get the previous session should never be invoked because the |
| 1032 // SessionService was destroyed before SessionService could process the results. |
| 1033 TEST_F(SessionServiceTest, GetSessionsAndDestroy) { |
| 1034 base::CancelableTaskTracker cancelable_task_tracker; |
| 1035 base::RunLoop run_loop; |
| 1036 base::WaitableEvent event(true, false); |
| 1037 helper_.RunTaskOnBackendThread(FROM_HERE, |
| 1038 base::Bind(&base::WaitableEvent::Wait, |
| 1039 base::Unretained(&event))); |
| 1040 service()->GetLastSession(base::Bind(&OnGotPreviousSession), |
| 1041 &cancelable_task_tracker); |
| 1042 helper_.RunTaskOnBackendThread( |
| 1043 FROM_HERE, |
| 1044 base::Bind(&PostBackToThread, |
| 1045 base::Unretained(base::MessageLoop::current()), |
| 1046 base::Unretained(&run_loop))); |
| 1047 delete helper_.ReleaseService(); |
| 1048 event.Signal(); |
| 1049 run_loop.Run(); |
| 1050 } |
OLD | NEW |