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 "chrome/browser/sync/test/integration/sessions_helper.h" | 5 #include "chrome/browser/sync/test/integration/sessions_helper.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <set> | 9 #include <set> |
10 #include <utility> | 10 #include <utility> |
11 | 11 |
12 #include "base/bind.h" | 12 #include "base/bind.h" |
13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
14 #include "base/location.h" | 14 #include "base/location.h" |
15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
16 #include "base/memory/weak_ptr.h" | 16 #include "base/memory/weak_ptr.h" |
17 #include "base/single_thread_task_runner.h" | 17 #include "base/single_thread_task_runner.h" |
18 #include "base/test/test_timeouts.h" | 18 #include "base/test/test_timeouts.h" |
19 #include "base/threading/thread_task_runner_handle.h" | 19 #include "base/threading/thread_task_runner_handle.h" |
20 #include "base/time/time.h" | 20 #include "base/time/time.h" |
21 #include "chrome/browser/profiles/profile.h" | 21 #include "chrome/browser/profiles/profile.h" |
22 #include "chrome/browser/sync/profile_sync_service_factory.h" | 22 #include "chrome/browser/sync/profile_sync_service_factory.h" |
23 #include "chrome/browser/sync/sessions/notification_service_sessions_router.h" | |
24 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" | 23 #include "chrome/browser/sync/test/integration/profile_sync_service_harness.h" |
25 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h" | 24 #include "chrome/browser/sync/test/integration/sync_datatype_helper.h" |
26 #include "chrome/browser/ui/browser.h" | 25 #include "chrome/browser/ui/browser.h" |
27 #include "chrome/browser/ui/browser_tabstrip.h" | 26 #include "chrome/browser/ui/browser_tabstrip.h" |
28 #include "chrome/browser/ui/singleton_tabs.h" | 27 #include "chrome/browser/ui/singleton_tabs.h" |
29 #include "chrome/browser/ui/tabs/tab_strip_model.h" | 28 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
30 #include "chrome/common/chrome_switches.h" | 29 #include "chrome/common/chrome_switches.h" |
31 #include "chrome/test/base/ui_test_utils.h" | 30 #include "chrome/test/base/ui_test_utils.h" |
32 #include "components/browser_sync/profile_sync_service.h" | 31 #include "components/browser_sync/profile_sync_service.h" |
33 #include "components/sync/driver/sync_client.h" | 32 #include "components/sync/driver/sync_client.h" |
34 #include "components/sync/test/fake_server/fake_server.h" | 33 #include "components/sync/test/fake_server/fake_server.h" |
35 #include "components/sync/test/fake_server/sessions_hierarchy.h" | 34 #include "components/sync/test/fake_server/sessions_hierarchy.h" |
36 #include "components/sync_sessions/open_tabs_ui_delegate.h" | 35 #include "components/sync_sessions/open_tabs_ui_delegate.h" |
37 #include "content/public/browser/navigation_entry.h" | 36 #include "content/public/browser/navigation_entry.h" |
| 37 #include "content/public/browser/render_frame_host.h" |
| 38 #include "content/public/browser/render_process_host.h" |
38 #include "content/public/browser/web_contents.h" | 39 #include "content/public/browser/web_contents.h" |
| 40 #include "content/public/test/browser_test_utils.cc" |
39 #include "content/public/test/test_utils.h" | 41 #include "content/public/test/test_utils.h" |
40 #include "url/gurl.h" | 42 #include "url/gurl.h" |
41 | 43 |
42 using sync_datatype_helper::test; | 44 using sync_datatype_helper::test; |
43 | 45 |
44 namespace sessions_helper { | 46 namespace sessions_helper { |
45 | 47 |
46 bool GetLocalSession(int index, const sync_sessions::SyncedSession** session) { | 48 bool GetLocalSession(int index, const sync_sessions::SyncedSession** session) { |
47 return ProfileSyncServiceFactory::GetInstance() | 49 return ProfileSyncServiceFactory::GetInstance() |
48 ->GetForProfile(test()->GetProfile(index)) | 50 ->GetForProfile(test()->GetProfile(index)) |
49 ->GetOpenTabsUIDelegate() | 51 ->GetOpenTabsUIDelegate() |
50 ->GetLocalSession(session); | 52 ->GetLocalSession(session); |
51 } | 53 } |
52 | 54 |
53 bool ModelAssociatorHasTabWithUrl(int index, const GURL& url) { | 55 bool SessionsSyncManagerHasTabWithURL(int index, const GURL& url) { |
54 content::RunAllPendingInMessageLoop(); | 56 content::RunAllPendingInMessageLoop(); |
55 const sync_sessions::SyncedSession* local_session; | 57 const sync_sessions::SyncedSession* local_session; |
56 if (!GetLocalSession(index, &local_session)) { | 58 if (!GetLocalSession(index, &local_session)) { |
57 return false; | 59 return false; |
58 } | 60 } |
59 | 61 |
60 if (local_session->windows.size() == 0) { | 62 if (local_session->windows.size() == 0) { |
61 DVLOG(1) << "Empty windows vector"; | 63 DVLOG(1) << "Empty windows vector"; |
62 return false; | 64 return false; |
63 } | 65 } |
(...skipping 30 matching lines...) Expand all Loading... |
94 } | 96 } |
95 | 97 |
96 bool OpenTab(int index, const GURL& url) { | 98 bool OpenTab(int index, const GURL& url) { |
97 DVLOG(1) << "Opening tab: " << url.spec() << " using browser " << index | 99 DVLOG(1) << "Opening tab: " << url.spec() << " using browser " << index |
98 << "."; | 100 << "."; |
99 return OpenTabAtIndex(index, 0, url); | 101 return OpenTabAtIndex(index, 0, url); |
100 } | 102 } |
101 | 103 |
102 bool OpenTabAtIndex(int index, int tab_index, const GURL& url) { | 104 bool OpenTabAtIndex(int index, int tab_index, const GURL& url) { |
103 chrome::AddTabAt(test()->GetBrowser(index), url, tab_index, true); | 105 chrome::AddTabAt(test()->GetBrowser(index), url, tab_index, true); |
104 return WaitForTabsToLoad(index, {url}); | 106 return WaitForTabToLoad( |
| 107 index, url, |
| 108 test()->GetBrowser(index)->tab_strip_model()->GetWebContentsAt( |
| 109 tab_index)); |
105 } | 110 } |
106 | 111 |
107 bool OpenMultipleTabs(int index, const std::vector<GURL>& urls) { | 112 bool OpenMultipleTabs(int index, const std::vector<GURL>& urls) { |
108 Browser* browser = test()->GetBrowser(index); | 113 Browser* browser = test()->GetBrowser(index); |
109 for (std::vector<GURL>::const_iterator it = urls.begin(); | 114 for (std::vector<GURL>::const_iterator it = urls.begin(); |
110 it != urls.end(); ++it) { | 115 it != urls.end(); ++it) { |
111 DVLOG(1) << "Opening tab: " << it->spec() << " using browser " << index | 116 DVLOG(1) << "Opening tab: " << it->spec() << " using browser " << index |
112 << "."; | 117 << "."; |
113 chrome::ShowSingletonTab(browser, *it); | 118 chrome::ShowSingletonTab(browser, *it); |
114 } | 119 } |
115 return WaitForTabsToLoad(index, urls); | 120 return WaitForTabsToLoad(index, urls); |
116 } | 121 } |
117 | 122 |
| 123 bool OpenTabFromSourceIndex(int index, |
| 124 int index_of_source_tab, |
| 125 const GURL& url, |
| 126 WindowOpenDisposition disposition) { |
| 127 content::WebContents* source_contents = |
| 128 test()->GetBrowser(index)->tab_strip_model()->GetWebContentsAt( |
| 129 index_of_source_tab); |
| 130 |
| 131 content::OpenURLParams open_url_params(url, content::Referrer(), disposition, |
| 132 ui::PAGE_TRANSITION_LINK, false, |
| 133 false); |
| 134 open_url_params.source_render_frame_id = |
| 135 source_contents->GetMainFrame()->GetRoutingID(); |
| 136 open_url_params.source_render_process_id = |
| 137 source_contents->GetRenderProcessHost()->GetID(); |
| 138 |
| 139 content::WebContents* new_contents = |
| 140 source_contents->OpenURL(open_url_params); |
| 141 if (!new_contents) { |
| 142 return false; |
| 143 } |
| 144 |
| 145 return WaitForTabToLoad(index, url, new_contents); |
| 146 } |
| 147 |
118 void MoveTab(int from_index, int to_index, int tab_index) { | 148 void MoveTab(int from_index, int to_index, int tab_index) { |
119 content::WebContents* detached_contents = | 149 content::WebContents* detached_contents = |
120 test() | 150 test() |
121 ->GetBrowser(from_index) | 151 ->GetBrowser(from_index) |
122 ->tab_strip_model() | 152 ->tab_strip_model() |
123 ->DetachWebContentsAt(tab_index); | 153 ->DetachWebContentsAt(tab_index); |
124 | 154 |
125 TabStripModel* target_strip = test()->GetBrowser(to_index)->tab_strip_model(); | 155 TabStripModel* target_strip = test()->GetBrowser(to_index)->tab_strip_model(); |
126 target_strip->InsertWebContentsAt(target_strip->count(), detached_contents, | 156 target_strip->InsertWebContentsAt(target_strip->count(), detached_contents, |
127 TabStripModel::ADD_ACTIVE); | 157 TabStripModel::ADD_ACTIVE); |
128 } | 158 } |
129 | 159 |
130 bool NavigateTab(int index, const GURL& url) { | 160 bool NavigateTab(int index, const GURL& url) { |
131 chrome::NavigateParams params(test()->GetBrowser(index), url, | 161 chrome::NavigateParams params(test()->GetBrowser(index), url, |
132 ui::PAGE_TRANSITION_LINK); | 162 ui::PAGE_TRANSITION_LINK); |
133 params.disposition = WindowOpenDisposition::CURRENT_TAB; | 163 params.disposition = WindowOpenDisposition::CURRENT_TAB; |
134 | 164 |
135 ui_test_utils::NavigateToURL(¶ms); | 165 ui_test_utils::NavigateToURL(¶ms); |
136 return WaitForTabsToLoad(index, {url}); | 166 return WaitForTabToLoad(index, url, params.target_contents); |
137 } | 167 } |
138 | 168 |
139 void NavigateTabBack(int index) { | 169 void NavigateTabBack(int index) { |
140 test() | 170 test() |
141 ->GetBrowser(index) | 171 ->GetBrowser(index) |
142 ->tab_strip_model() | 172 ->tab_strip_model() |
143 ->GetWebContentsAt(0) | 173 ->GetWebContentsAt(0) |
144 ->GetController() | 174 ->GetController() |
145 .GoBack(); | 175 .GoBack(); |
146 } | 176 } |
147 | 177 |
148 void NavigateTabForward(int index) { | 178 void NavigateTabForward(int index) { |
149 test() | 179 test() |
150 ->GetBrowser(index) | 180 ->GetBrowser(index) |
151 ->tab_strip_model() | 181 ->tab_strip_model() |
152 ->GetWebContentsAt(0) | 182 ->GetWebContentsAt(0) |
153 ->GetController() | 183 ->GetController() |
154 .GoForward(); | 184 .GoForward(); |
155 } | 185 } |
156 | 186 |
157 namespace { | 187 bool WaitForTabsToLoad(int index, const std::vector<GURL>& urls) { |
| 188 int tab_index = 0; |
| 189 for (const auto& url : urls) { |
| 190 bool success = WaitForTabToLoad( |
| 191 index, url, |
| 192 test()->GetBrowser(index)->tab_strip_model()->GetWebContentsAt( |
| 193 tab_index)); |
| 194 if (!success) { |
| 195 return false; |
| 196 } |
| 197 tab_index++; |
| 198 } |
| 199 return true; |
| 200 } |
158 | 201 |
159 class TabEventHandler : public sync_sessions::LocalSessionEventHandler { | 202 bool WaitForTabToLoad(int index, |
160 public: | 203 const GURL& url, |
161 TabEventHandler() : weak_factory_(this) { | 204 content::WebContents* web_contents) { |
162 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( | |
163 FROM_HERE, | |
164 base::Bind(&TabEventHandler::QuitLoop, weak_factory_.GetWeakPtr()), | |
165 TestTimeouts::action_max_timeout()); | |
166 } | |
167 | |
168 void OnLocalTabModified( | |
169 sync_sessions::SyncedTabDelegate* modified_tab) override { | |
170 // Unwind to ensure SessionsSyncManager has processed the event. | |
171 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
172 FROM_HERE, | |
173 base::Bind(&TabEventHandler::QuitLoop, weak_factory_.GetWeakPtr())); | |
174 } | |
175 | |
176 void OnFaviconsChanged(const std::set<GURL>& /* page_urls */, | |
177 const GURL& /* icon_url */) override { | |
178 // Unwind to ensure SessionsSyncManager has processed the event. | |
179 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
180 FROM_HERE, | |
181 base::Bind(&TabEventHandler::QuitLoop, weak_factory_.GetWeakPtr())); | |
182 } | |
183 | |
184 private: | |
185 void QuitLoop() { base::MessageLoop::current()->QuitWhenIdle(); } | |
186 | |
187 base::WeakPtrFactory<TabEventHandler> weak_factory_; | |
188 }; | |
189 | |
190 } // namespace | |
191 | |
192 bool WaitForTabsToLoad(int index, const std::vector<GURL>& urls) { | |
193 DVLOG(1) << "Waiting for session to propagate to associator."; | 205 DVLOG(1) << "Waiting for session to propagate to associator."; |
194 base::TimeTicks start_time = base::TimeTicks::Now(); | 206 base::TimeTicks start_time = base::TimeTicks::Now(); |
195 base::TimeTicks end_time = start_time + TestTimeouts::action_max_timeout(); | 207 base::TimeTicks end_time = start_time + TestTimeouts::action_max_timeout(); |
196 bool found; | 208 bool found = false; |
197 for (std::vector<GURL>::const_iterator it = urls.begin(); | 209 while (!found) { |
198 it != urls.end(); ++it) { | 210 found = SessionsSyncManagerHasTabWithURL(index, url); |
199 found = false; | 211 if (base::TimeTicks::Now() >= end_time) { |
200 while (!found) { | 212 LOG(ERROR) << "Failed to find url " << url.spec() << " in tab after " |
201 found = ModelAssociatorHasTabWithUrl(index, *it); | 213 << TestTimeouts::action_max_timeout().InSecondsF() |
202 if (base::TimeTicks::Now() >= end_time) { | 214 << " seconds."; |
203 LOG(ERROR) << "Failed to find all tabs after " | 215 return false; |
204 << TestTimeouts::action_max_timeout().InSecondsF() | 216 } |
205 << " seconds."; | 217 if (!found) { |
206 return false; | 218 content::WaitForLoadStop(web_contents); |
207 } | |
208 if (!found) { | |
209 TabEventHandler handler; | |
210 sync_sessions::NotificationServiceSessionsRouter router( | |
211 test()->GetProfile(index), | |
212 ProfileSyncServiceFactory::GetInstance() | |
213 ->GetForProfile(test()->GetProfile(index)) | |
214 ->GetSyncClient() | |
215 ->GetSyncSessionsClient(), | |
216 syncer::SyncableService::StartSyncFlare()); | |
217 router.StartRoutingTo(&handler); | |
218 content::RunMessageLoop(); | |
219 } | |
220 } | 219 } |
221 } | 220 } |
222 return true; | 221 return true; |
223 } | 222 } |
224 | 223 |
225 bool GetLocalWindows(int index, ScopedWindowMap* local_windows) { | 224 bool GetLocalWindows(int index, ScopedWindowMap* local_windows) { |
226 // The local session provided by GetLocalSession is owned, and has lifetime | 225 // The local session provided by GetLocalSession is owned, and has lifetime |
227 // controlled, by the model associator, so we must make our own copy. | 226 // controlled, by the sessions sync manager, so we must make our own copy. |
228 const sync_sessions::SyncedSession* local_session; | 227 const sync_sessions::SyncedSession* local_session; |
229 if (!GetLocalSession(index, &local_session)) { | 228 if (!GetLocalSession(index, &local_session)) { |
230 return false; | 229 return false; |
231 } | 230 } |
232 for (auto w = local_session->windows.begin(); | 231 for (auto w = local_session->windows.begin(); |
233 w != local_session->windows.end(); ++w) { | 232 w != local_session->windows.end(); ++w) { |
234 const sessions::SessionWindow& window = *(w->second); | 233 const sessions::SessionWindow& window = *(w->second); |
235 std::unique_ptr<sessions::SessionWindow> new_window = | 234 std::unique_ptr<sessions::SessionWindow> new_window = |
236 base::MakeUnique<sessions::SessionWindow>(); | 235 base::MakeUnique<sessions::SessionWindow>(); |
237 new_window->window_id.set_id(window.window_id.id()); | 236 new_window->window_id.set_id(window.window_id.id()); |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
436 index_(index), | 435 index_(index), |
437 windows_(windows) {} | 436 windows_(windows) {} |
438 | 437 |
439 bool ForeignSessionsMatchChecker::IsExitConditionSatisfied() { | 438 bool ForeignSessionsMatchChecker::IsExitConditionSatisfied() { |
440 return sessions_helper::CheckForeignSessionsAgainst(index_, windows_); | 439 return sessions_helper::CheckForeignSessionsAgainst(index_, windows_); |
441 } | 440 } |
442 | 441 |
443 std::string ForeignSessionsMatchChecker::GetDebugMessage() const { | 442 std::string ForeignSessionsMatchChecker::GetDebugMessage() const { |
444 return "Waiting for matching foreign sessions"; | 443 return "Waiting for matching foreign sessions"; |
445 } | 444 } |
OLD | NEW |