OLD | NEW |
| (Empty) |
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 | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/ui/panels/base_panel_browser_test.h" | |
6 | |
7 #include <string.h> | |
8 | |
9 #include "base/bind.h" | |
10 #include "base/command_line.h" | |
11 #include "base/macros.h" | |
12 #include "base/memory/weak_ptr.h" | |
13 #include "base/message_loop/message_loop.h" | |
14 #include "base/strings/string_number_conversions.h" | |
15 #include "build/build_config.h" | |
16 #include "chrome/browser/chrome_notification_types.h" | |
17 #include "chrome/browser/extensions/extension_service.h" | |
18 #include "chrome/browser/profiles/profile.h" | |
19 #include "chrome/browser/ui/browser.h" | |
20 #include "chrome/browser/ui/browser_window.h" | |
21 #include "chrome/browser/ui/panels/detached_panel_collection.h" | |
22 #include "chrome/browser/ui/panels/native_panel.h" | |
23 #include "chrome/browser/ui/panels/panel_collection.h" | |
24 #include "chrome/browser/ui/panels/panel_mouse_watcher.h" | |
25 #include "chrome/browser/ui/panels/stacked_panel_collection.h" | |
26 #include "chrome/browser/ui/panels/test_panel_active_state_observer.h" | |
27 #include "chrome/browser/ui/panels/test_panel_mouse_watcher.h" | |
28 #include "chrome/common/chrome_paths.h" | |
29 #include "chrome/common/chrome_switches.h" | |
30 #include "chrome/test/base/interactive_test_utils.h" | |
31 #include "chrome/test/base/ui_test_utils.h" | |
32 #include "components/sync/api/string_ordinal.h" | |
33 #include "content/public/browser/notification_service.h" | |
34 #include "content/public/common/url_constants.h" | |
35 #include "content/public/test/web_contents_tester.h" | |
36 #include "extensions/browser/extension_prefs.h" | |
37 #include "extensions/browser/extension_system.h" | |
38 #include "extensions/browser/install_flag.h" | |
39 #include "extensions/common/manifest_constants.h" | |
40 | |
41 #if defined(OS_LINUX) | |
42 #include "ui/base/x/x11_util.h" | |
43 #endif | |
44 | |
45 #if defined(OS_MACOSX) | |
46 #include "base/mac/scoped_nsautorelease_pool.h" | |
47 #include "chrome/browser/ui/cocoa/run_loop_testing.h" | |
48 #endif | |
49 | |
50 using content::WebContentsTester; | |
51 using extensions::Extension; | |
52 | |
53 namespace { | |
54 | |
55 const gfx::Rect kTestingPrimaryDisplayArea = gfx::Rect(0, 0, 800, 600); | |
56 const gfx::Rect kTestingPrimaryWorkArea = gfx::Rect(0, 0, 800, 580); | |
57 | |
58 struct MockDesktopBar { | |
59 bool auto_hiding_enabled; | |
60 DisplaySettingsProvider::DesktopBarVisibility visibility; | |
61 int thickness; | |
62 }; | |
63 | |
64 class MockDisplaySettingsProviderImpl : | |
65 public BasePanelBrowserTest::MockDisplaySettingsProvider { | |
66 public: | |
67 MockDisplaySettingsProviderImpl(); | |
68 ~MockDisplaySettingsProviderImpl() override {} | |
69 | |
70 // Overridden from DisplaySettingsProvider: | |
71 gfx::Rect GetPrimaryDisplayArea() const override; | |
72 gfx::Rect GetPrimaryWorkArea() const override; | |
73 gfx::Rect GetDisplayAreaMatching(const gfx::Rect& bounds) const override; | |
74 gfx::Rect GetWorkAreaMatching(const gfx::Rect& bounds) const override; | |
75 bool IsAutoHidingDesktopBarEnabled(DesktopBarAlignment alignment) override; | |
76 int GetDesktopBarThickness(DesktopBarAlignment alignment) const override; | |
77 DesktopBarVisibility GetDesktopBarVisibility( | |
78 DesktopBarAlignment alignment) const override; | |
79 bool IsFullScreen() override; | |
80 | |
81 // Overridden from MockDisplaySettingsProvider: | |
82 void SetPrimaryDisplay(const gfx::Rect& display_area, | |
83 const gfx::Rect& work_area) override; | |
84 void SetSecondaryDisplay(const gfx::Rect& display_area, | |
85 const gfx::Rect& work_area) override; | |
86 void EnableAutoHidingDesktopBar(DesktopBarAlignment alignment, | |
87 bool enabled, | |
88 int thickness) override; | |
89 void SetDesktopBarVisibility(DesktopBarAlignment alignment, | |
90 DesktopBarVisibility visibility) override; | |
91 void SetDesktopBarThickness(DesktopBarAlignment alignment, | |
92 int thickness) override; | |
93 void EnableFullScreenMode(bool enabled) override; | |
94 | |
95 private: | |
96 gfx::Rect primary_display_area_; | |
97 gfx::Rect primary_work_area_; | |
98 gfx::Rect secondary_display_area_; | |
99 gfx::Rect secondary_work_area_; | |
100 MockDesktopBar mock_desktop_bars[3]; | |
101 bool full_screen_enabled_; | |
102 | |
103 DISALLOW_COPY_AND_ASSIGN(MockDisplaySettingsProviderImpl); | |
104 }; | |
105 | |
106 | |
107 MockDisplaySettingsProviderImpl::MockDisplaySettingsProviderImpl() | |
108 : full_screen_enabled_(false) { | |
109 memset(mock_desktop_bars, 0, sizeof(mock_desktop_bars)); | |
110 } | |
111 | |
112 gfx::Rect MockDisplaySettingsProviderImpl::GetPrimaryDisplayArea() const { | |
113 return primary_display_area_; | |
114 } | |
115 | |
116 gfx::Rect MockDisplaySettingsProviderImpl::GetPrimaryWorkArea() const { | |
117 return primary_work_area_; | |
118 } | |
119 | |
120 gfx::Rect MockDisplaySettingsProviderImpl::GetDisplayAreaMatching( | |
121 const gfx::Rect& bounds) const { | |
122 if (secondary_display_area_.IsEmpty()) | |
123 return primary_display_area_; | |
124 | |
125 gfx::Rect primary_intersection = | |
126 gfx::IntersectRects(bounds, primary_display_area_); | |
127 int primary_intersection_size = | |
128 primary_intersection.width() * primary_intersection.height(); | |
129 | |
130 gfx::Rect secondary_intersection = | |
131 gfx::IntersectRects(bounds, secondary_display_area_); | |
132 int secondary_intersection_size = | |
133 secondary_intersection.width() * secondary_intersection.height(); | |
134 | |
135 return primary_intersection_size >= secondary_intersection_size ? | |
136 primary_display_area_ : secondary_display_area_; | |
137 } | |
138 | |
139 gfx::Rect MockDisplaySettingsProviderImpl::GetWorkAreaMatching( | |
140 const gfx::Rect& bounds) const { | |
141 if (secondary_work_area_.IsEmpty()) | |
142 return primary_work_area_; | |
143 | |
144 gfx::Rect primary_intersection = | |
145 gfx::IntersectRects(bounds, primary_work_area_); | |
146 int primary_intersection_size = | |
147 primary_intersection.width() * primary_intersection.height(); | |
148 | |
149 gfx::Rect secondary_intersection = | |
150 gfx::IntersectRects(bounds, secondary_work_area_); | |
151 int secondary_intersection_size = | |
152 secondary_intersection.width() * secondary_intersection.height(); | |
153 | |
154 return primary_intersection_size >= secondary_intersection_size ? | |
155 primary_work_area_ : secondary_work_area_; | |
156 } | |
157 | |
158 bool MockDisplaySettingsProviderImpl::IsAutoHidingDesktopBarEnabled( | |
159 DesktopBarAlignment alignment) { | |
160 return mock_desktop_bars[static_cast<int>(alignment)].auto_hiding_enabled; | |
161 } | |
162 | |
163 int MockDisplaySettingsProviderImpl::GetDesktopBarThickness( | |
164 DesktopBarAlignment alignment) const { | |
165 return mock_desktop_bars[static_cast<int>(alignment)].thickness; | |
166 } | |
167 | |
168 DisplaySettingsProvider::DesktopBarVisibility | |
169 MockDisplaySettingsProviderImpl::GetDesktopBarVisibility( | |
170 DesktopBarAlignment alignment) const { | |
171 return mock_desktop_bars[static_cast<int>(alignment)].visibility; | |
172 } | |
173 | |
174 bool MockDisplaySettingsProviderImpl::IsFullScreen() { | |
175 return full_screen_enabled_; | |
176 } | |
177 | |
178 void MockDisplaySettingsProviderImpl::EnableAutoHidingDesktopBar( | |
179 DesktopBarAlignment alignment, bool enabled, int thickness) { | |
180 MockDesktopBar* bar = &(mock_desktop_bars[static_cast<int>(alignment)]); | |
181 bar->auto_hiding_enabled = enabled; | |
182 bar->thickness = thickness; | |
183 } | |
184 | |
185 void MockDisplaySettingsProviderImpl::SetPrimaryDisplay( | |
186 const gfx::Rect& display_area, const gfx::Rect& work_area) { | |
187 DCHECK(display_area.Contains(work_area)); | |
188 primary_display_area_ = display_area; | |
189 primary_work_area_ = work_area; | |
190 OnDisplaySettingsChanged(); | |
191 } | |
192 | |
193 void MockDisplaySettingsProviderImpl::SetSecondaryDisplay( | |
194 const gfx::Rect& display_area, const gfx::Rect& work_area) { | |
195 DCHECK(display_area.Contains(work_area)); | |
196 secondary_display_area_ = display_area; | |
197 secondary_work_area_ = work_area; | |
198 OnDisplaySettingsChanged(); | |
199 } | |
200 | |
201 void MockDisplaySettingsProviderImpl::SetDesktopBarVisibility( | |
202 DesktopBarAlignment alignment, DesktopBarVisibility visibility) { | |
203 MockDesktopBar* bar = &(mock_desktop_bars[static_cast<int>(alignment)]); | |
204 if (!bar->auto_hiding_enabled) | |
205 return; | |
206 if (visibility == bar->visibility) | |
207 return; | |
208 bar->visibility = visibility; | |
209 FOR_EACH_OBSERVER( | |
210 DesktopBarObserver, | |
211 desktop_bar_observers(), | |
212 OnAutoHidingDesktopBarVisibilityChanged(alignment, visibility)); | |
213 } | |
214 | |
215 void MockDisplaySettingsProviderImpl::SetDesktopBarThickness( | |
216 DesktopBarAlignment alignment, int thickness) { | |
217 MockDesktopBar* bar = &(mock_desktop_bars[static_cast<int>(alignment)]); | |
218 if (!bar->auto_hiding_enabled) | |
219 return; | |
220 if (thickness == bar->thickness) | |
221 return; | |
222 bar->thickness = thickness; | |
223 FOR_EACH_OBSERVER( | |
224 DesktopBarObserver, | |
225 desktop_bar_observers(), | |
226 OnAutoHidingDesktopBarThicknessChanged(alignment, thickness)); | |
227 } | |
228 | |
229 void MockDisplaySettingsProviderImpl::EnableFullScreenMode(bool enabled) { | |
230 full_screen_enabled_ = enabled; | |
231 CheckFullScreenMode(PERFORM_FULLSCREEN_CHECK); | |
232 } | |
233 | |
234 } // namespace | |
235 | |
236 const base::FilePath::CharType* BasePanelBrowserTest::kTestDir = | |
237 FILE_PATH_LITERAL("panels"); | |
238 | |
239 BasePanelBrowserTest::BasePanelBrowserTest() | |
240 : InProcessBrowserTest(), | |
241 mock_display_settings_enabled_(true) { | |
242 } | |
243 | |
244 BasePanelBrowserTest::~BasePanelBrowserTest() { | |
245 } | |
246 | |
247 void BasePanelBrowserTest::SetUpCommandLine(base::CommandLine* command_line) { | |
248 command_line->AppendSwitch(switches::kEnablePanels); | |
249 } | |
250 | |
251 void BasePanelBrowserTest::SetUpOnMainThread() { | |
252 InProcessBrowserTest::SetUpOnMainThread(); | |
253 | |
254 // Setup the work area and desktop bar so that we have consistent testing | |
255 // environment for all panel related tests. | |
256 if (mock_display_settings_enabled_) { | |
257 mock_display_settings_provider_ = new MockDisplaySettingsProviderImpl(); | |
258 mock_display_settings_provider_->SetPrimaryDisplay( | |
259 kTestingPrimaryDisplayArea, kTestingPrimaryWorkArea); | |
260 PanelManager::SetDisplaySettingsProviderForTesting( | |
261 mock_display_settings_provider_); | |
262 } | |
263 | |
264 PanelManager* panel_manager = PanelManager::GetInstance(); | |
265 panel_manager->enable_auto_sizing(false); | |
266 | |
267 PanelManager::shorten_time_intervals_for_testing(); | |
268 | |
269 // Simulate the mouse movement so that tests are not affected by actual mouse | |
270 // events. | |
271 PanelMouseWatcher* mouse_watcher = new TestPanelMouseWatcher(); | |
272 panel_manager->SetMouseWatcherForTesting(mouse_watcher); | |
273 | |
274 // This is needed so the subsequently created panels can be activated. | |
275 // On a Mac, it transforms background-only test process into foreground one. | |
276 ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); | |
277 } | |
278 | |
279 void BasePanelBrowserTest::WaitForPanelActiveState( | |
280 Panel* panel, ActiveState expected_state) { | |
281 DCHECK(expected_state == SHOW_AS_ACTIVE || | |
282 expected_state == SHOW_AS_INACTIVE); | |
283 | |
284 #if defined(OS_MACOSX) | |
285 std::unique_ptr<NativePanelTesting> panel_testing( | |
286 CreateNativePanelTesting(panel)); | |
287 ASSERT_TRUE(panel_testing->EnsureApplicationRunOnForeground()) << | |
288 "Failed to bring application to foreground. Bail out."; | |
289 #endif | |
290 | |
291 PanelActiveStateObserver signal(panel, expected_state == SHOW_AS_ACTIVE); | |
292 signal.Wait(); | |
293 } | |
294 | |
295 void BasePanelBrowserTest::WaitForBoundsAnimationFinished(Panel* panel) { | |
296 std::unique_ptr<NativePanelTesting> panel_testing( | |
297 CreateNativePanelTesting(panel)); | |
298 // Sometimes there are several animations in sequence due to content | |
299 // auto resizing. Wait for all animations to finish. | |
300 while (panel_testing->IsAnimatingBounds()) { | |
301 content::WindowedNotificationObserver signal( | |
302 chrome::NOTIFICATION_PANEL_BOUNDS_ANIMATIONS_FINISHED, | |
303 content::Source<Panel>(panel)); | |
304 if (!panel_testing->IsAnimatingBounds()) | |
305 return; | |
306 signal.Wait(); | |
307 } | |
308 } | |
309 | |
310 BasePanelBrowserTest::CreatePanelParams::CreatePanelParams( | |
311 const std::string& name, | |
312 const gfx::Rect& bounds, | |
313 ActiveState show_flag) | |
314 : name(name), | |
315 bounds(bounds), | |
316 show_flag(show_flag), | |
317 wait_for_fully_created(true), | |
318 expected_active_state(show_flag), | |
319 create_mode(PanelManager::CREATE_AS_DOCKED), | |
320 profile(NULL) { | |
321 } | |
322 | |
323 Panel* BasePanelBrowserTest::CreatePanelWithParams( | |
324 const CreatePanelParams& params) { | |
325 #if defined(OS_MACOSX) | |
326 // Opening panels on a Mac causes NSWindowController of the Panel window | |
327 // to be autoreleased. We need a pool drained after it's done so the test | |
328 // can close correctly. The NSWindowController of the Panel window controls | |
329 // lifetime of the Panel object so we want to release it as soon as | |
330 // possible. In real Chrome, this is done by message pump. | |
331 // On non-Mac platform, this is an empty class. | |
332 base::mac::ScopedNSAutoreleasePool autorelease_pool; | |
333 #endif | |
334 | |
335 content::WindowedNotificationObserver observer( | |
336 content::NOTIFICATION_LOAD_STOP, | |
337 content::NotificationService::AllSources()); | |
338 | |
339 PanelManager* manager = PanelManager::GetInstance(); | |
340 Panel* panel = manager->CreatePanel( | |
341 params.name, | |
342 params.profile ? params.profile : browser()->profile(), | |
343 params.url, | |
344 nullptr, | |
345 params.bounds, | |
346 params.create_mode); | |
347 | |
348 if (!params.url.is_empty()) | |
349 observer.Wait(); | |
350 | |
351 if (!manager->auto_sizing_enabled() || | |
352 params.bounds.width() || params.bounds.height()) { | |
353 EXPECT_FALSE(panel->auto_resizable()); | |
354 } else { | |
355 EXPECT_TRUE(panel->auto_resizable()); | |
356 } | |
357 | |
358 if (params.show_flag == SHOW_AS_ACTIVE) { | |
359 panel->Show(); | |
360 } else { | |
361 panel->ShowInactive(); | |
362 } | |
363 | |
364 if (params.wait_for_fully_created) { | |
365 base::MessageLoopForUI::current()->RunUntilIdle(); | |
366 | |
367 #if defined(OS_LINUX) && defined(USE_X11) | |
368 // On bots, we might have a simple window manager which always activates new | |
369 // windows, and can't always deactivate them. Re-activate the main tabbed | |
370 // browser to "deactivate" the newly created panel. | |
371 if (params.expected_active_state == SHOW_AS_INACTIVE && | |
372 ui::GuessWindowManager() == ui::WM_ICE_WM) { | |
373 // Wait for new panel to become active before deactivating to ensure | |
374 // the activated notification is consumed before we wait for the panel | |
375 // to become inactive. | |
376 WaitForPanelActiveState(panel, SHOW_AS_ACTIVE); | |
377 browser()->window()->Activate(); | |
378 } | |
379 #endif | |
380 // More waiting, because gaining or losing focus may require inter-process | |
381 // asynchronous communication, and it is not enough to just run the local | |
382 // message loop to make sure this activity has completed. | |
383 WaitForPanelActiveState(panel, params.expected_active_state); | |
384 | |
385 // Wait for the bounds animations on creation to finish. | |
386 WaitForBoundsAnimationFinished(panel); | |
387 } | |
388 | |
389 return panel; | |
390 } | |
391 | |
392 Panel* BasePanelBrowserTest::CreatePanelWithBounds( | |
393 const std::string& panel_name, const gfx::Rect& bounds) { | |
394 CreatePanelParams params(panel_name, bounds, SHOW_AS_ACTIVE); | |
395 return CreatePanelWithParams(params); | |
396 } | |
397 | |
398 Panel* BasePanelBrowserTest::CreatePanel(const std::string& panel_name) { | |
399 CreatePanelParams params(panel_name, gfx::Rect(), SHOW_AS_ACTIVE); | |
400 return CreatePanelWithParams(params); | |
401 } | |
402 | |
403 Panel* BasePanelBrowserTest::CreateDockedPanel(const std::string& name, | |
404 const gfx::Rect& bounds) { | |
405 Panel* panel = CreatePanelWithBounds(name, bounds); | |
406 EXPECT_EQ(PanelCollection::DOCKED, panel->collection()->type()); | |
407 return panel; | |
408 } | |
409 | |
410 Panel* BasePanelBrowserTest::CreateDetachedPanel(const std::string& name, | |
411 const gfx::Rect& bounds) { | |
412 Panel* panel = CreatePanelWithBounds(name, bounds); | |
413 PanelManager* panel_manager = panel->manager(); | |
414 panel_manager->MovePanelToCollection(panel, | |
415 panel_manager->detached_collection(), | |
416 PanelCollection::DEFAULT_POSITION); | |
417 EXPECT_EQ(PanelCollection::DETACHED, panel->collection()->type()); | |
418 // The panel is first created as docked panel, which ignores the specified | |
419 // origin in |bounds|. We need to reposition the panel after it becomes | |
420 // detached. | |
421 panel->SetPanelBounds(bounds); | |
422 WaitForBoundsAnimationFinished(panel); | |
423 return panel; | |
424 } | |
425 | |
426 Panel* BasePanelBrowserTest::CreateStackedPanel(const std::string& name, | |
427 const gfx::Rect& bounds, | |
428 StackedPanelCollection* stack) { | |
429 Panel* panel = CreateDetachedPanel(name, bounds); | |
430 panel->manager()->MovePanelToCollection( | |
431 panel, | |
432 stack, | |
433 static_cast<PanelCollection::PositioningMask>( | |
434 PanelCollection::DEFAULT_POSITION | | |
435 PanelCollection::COLLAPSE_TO_FIT)); | |
436 EXPECT_EQ(PanelCollection::STACKED, panel->collection()->type()); | |
437 WaitForBoundsAnimationFinished(panel); | |
438 return panel; | |
439 } | |
440 | |
441 Panel* BasePanelBrowserTest::CreateInactivePanel(const std::string& name) { | |
442 // Create an active panel first, instead of inactive panel. This is because | |
443 // certain window managers on Linux, like icewm, will always activate the | |
444 // new window. | |
445 Panel* panel = CreatePanel(name); | |
446 | |
447 DeactivatePanel(panel); | |
448 WaitForPanelActiveState(panel, SHOW_AS_INACTIVE); | |
449 | |
450 return panel; | |
451 } | |
452 | |
453 Panel* BasePanelBrowserTest::CreateInactiveDockedPanel( | |
454 const std::string& name, const gfx::Rect& bounds) { | |
455 // Create an active panel first, instead of inactive panel. This is because | |
456 // certain window managers on Linux, like icewm, will always activate the | |
457 // new window. | |
458 Panel* panel = CreateDockedPanel(name, bounds); | |
459 | |
460 DeactivatePanel(panel); | |
461 WaitForPanelActiveState(panel, SHOW_AS_INACTIVE); | |
462 | |
463 return panel; | |
464 } | |
465 | |
466 Panel* BasePanelBrowserTest::CreateInactiveDetachedPanel( | |
467 const std::string& name, const gfx::Rect& bounds) { | |
468 // Create an active panel first, instead of inactive panel. This is because | |
469 // certain window managers on Linux, like icewm, will always activate the | |
470 // new window. | |
471 Panel* panel = CreateDetachedPanel(name, bounds); | |
472 | |
473 DeactivatePanel(panel); | |
474 WaitForPanelActiveState(panel, SHOW_AS_INACTIVE); | |
475 | |
476 return panel; | |
477 } | |
478 | |
479 void BasePanelBrowserTest::ActivatePanel(Panel* panel) { | |
480 // For certain window managers on Linux, the window activation/deactivation | |
481 // signals might not be sent. To work around this, we explicitly deactivate | |
482 // all other panels first. | |
483 #if defined(OS_LINUX) | |
484 std::vector<Panel*> panels = PanelManager::GetInstance()->panels(); | |
485 for (std::vector<Panel*>::const_iterator iter = panels.begin(); | |
486 iter != panels.end(); ++iter) { | |
487 Panel* current_panel = *iter; | |
488 if (panel != current_panel) | |
489 current_panel->Deactivate(); | |
490 } | |
491 #endif | |
492 | |
493 panel->Activate(); | |
494 } | |
495 | |
496 void BasePanelBrowserTest::DeactivatePanel(Panel* panel) { | |
497 #if defined(OS_LINUX) | |
498 // For certain window managers on Linux, like icewm, panel activation and | |
499 // deactivation notification might not get tiggered when non-panel window is | |
500 // activated or deactivated. So we deactivate the panel directly. | |
501 panel->Deactivate(); | |
502 #else | |
503 // Make the panel lose focus by activating the browser window. This is | |
504 // because: | |
505 // 1) On Windows, deactivating the panel window might cause the application | |
506 // to lose the foreground status. When this occurs, trying to activate | |
507 // the panel window again will not be allowed by the system. | |
508 // 2) On MacOS, deactivating a window is not supported by Cocoa. | |
509 browser()->window()->Activate(); | |
510 #endif | |
511 } | |
512 | |
513 // static | |
514 NativePanelTesting* BasePanelBrowserTest::CreateNativePanelTesting( | |
515 Panel* panel) { | |
516 return panel->native_panel()->CreateNativePanelTesting(); | |
517 } | |
518 | |
519 scoped_refptr<Extension> BasePanelBrowserTest::CreateExtension( | |
520 const base::FilePath::StringType& path, | |
521 extensions::Manifest::Location location, | |
522 const base::DictionaryValue& extra_value) { | |
523 extensions::ExtensionPrefs* extension_prefs = | |
524 extensions::ExtensionPrefs::Get(browser()->profile()); | |
525 base::FilePath full_path = extension_prefs->install_directory().Append(path); | |
526 | |
527 std::unique_ptr<base::DictionaryValue> input_value(extra_value.DeepCopy()); | |
528 input_value->SetString(extensions::manifest_keys::kVersion, "1.0.0.0"); | |
529 input_value->SetString(extensions::manifest_keys::kName, "Sample Extension"); | |
530 | |
531 std::string error; | |
532 scoped_refptr<Extension> extension = Extension::Create( | |
533 full_path, location, *input_value, Extension::NO_FLAGS, &error); | |
534 EXPECT_TRUE(extension.get()); | |
535 EXPECT_STREQ("", error.c_str()); | |
536 extensions::ExtensionSystem::Get( | |
537 browser()->profile())->extension_service()->OnExtensionInstalled( | |
538 extension.get(), | |
539 syncer::StringOrdinal(), | |
540 extensions::kInstallFlagInstallImmediately); | |
541 return extension; | |
542 } | |
543 | |
544 void BasePanelBrowserTest::CloseWindowAndWait(Panel* panel) { | |
545 // Closing a panel may involve several async tasks. Need to use | |
546 // message pump and wait for the notification. | |
547 PanelManager* manager = PanelManager::GetInstance(); | |
548 int panel_count = manager->num_panels(); | |
549 content::WindowedNotificationObserver signal( | |
550 chrome::NOTIFICATION_PANEL_CLOSED, | |
551 content::Source<Panel>(panel)); | |
552 panel->Close(); | |
553 signal.Wait(); | |
554 // Now we have one less panel. | |
555 EXPECT_EQ(panel_count - 1, manager->num_panels()); | |
556 | |
557 #if defined(OS_MACOSX) | |
558 // Mac window controllers may be autoreleased, and in the non-test | |
559 // environment, may actually depend on the autorelease pool being recycled | |
560 // with the run loop in order to perform important work. Replicate this in | |
561 // the test environment. | |
562 AutoreleasePool()->Recycle(); | |
563 | |
564 // Make sure that everything has a chance to run. | |
565 chrome::testing::NSRunLoopRunAllPending(); | |
566 #endif // OS_MACOSX | |
567 } | |
568 | |
569 void BasePanelBrowserTest::MoveMouseAndWaitForExpansionStateChange( | |
570 Panel* panel, | |
571 const gfx::Point& position) { | |
572 content::WindowedNotificationObserver signal( | |
573 chrome::NOTIFICATION_PANEL_CHANGED_EXPANSION_STATE, | |
574 content::Source<Panel>(panel)); | |
575 MoveMouse(position); | |
576 signal.Wait(); | |
577 } | |
578 | |
579 void BasePanelBrowserTest::MoveMouse(const gfx::Point& position) { | |
580 PanelManager::GetInstance()->mouse_watcher()->NotifyMouseMovement(position); | |
581 } | |
582 | |
583 std::string BasePanelBrowserTest::MakePanelName(int index) { | |
584 std::string panel_name("Panel"); | |
585 return panel_name + base::IntToString(index); | |
586 } | |
587 | |
588 bool BasePanelBrowserTest::WmSupportWindowActivation() { | |
589 return true; | |
590 } | |
OLD | NEW |