OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "ash/wm/immersive_fullscreen_controller.h" | 5 #include "ash/wm/immersive_fullscreen_controller.h" |
6 | 6 |
7 #include "ash/display/display_manager.h" | 7 #include "ash/display/display_manager.h" |
8 #include "ash/root_window_controller.h" | 8 #include "ash/root_window_controller.h" |
9 #include "ash/screen_ash.h" | 9 #include "ash/screen_ash.h" |
10 #include "ash/shelf/shelf_layout_manager.h" | 10 #include "ash/shelf/shelf_layout_manager.h" |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 top_container_ = new views::View(); | 131 top_container_ = new views::View(); |
132 top_container_->SetBounds( | 132 top_container_->SetBounds( |
133 0, 0, widget_->GetWindowBoundsInScreen().width(), 100); | 133 0, 0, widget_->GetWindowBoundsInScreen().width(), 100); |
134 top_container_->set_focusable(true); | 134 top_container_->set_focusable(true); |
135 widget_->GetContentsView()->AddChildView(top_container_); | 135 widget_->GetContentsView()->AddChildView(top_container_); |
136 | 136 |
137 delegate_.reset( | 137 delegate_.reset( |
138 new MockImmersiveFullscreenControllerDelegate(top_container_)); | 138 new MockImmersiveFullscreenControllerDelegate(top_container_)); |
139 controller_.reset(new ImmersiveFullscreenController); | 139 controller_.reset(new ImmersiveFullscreenController); |
140 controller_->Init(delegate_.get(), widget_, top_container_); | 140 controller_->Init(delegate_.get(), widget_, top_container_); |
141 SetAnimationsDisabled(true); | 141 controller_->SetupForTest(); |
142 | 142 |
143 // The mouse is moved so that it is not over |top_container_| by | 143 // The mouse is moved so that it is not over |top_container_| by |
144 // AshTestBase. | 144 // AshTestBase. |
145 } | 145 } |
146 | 146 |
147 // Enable or disable the ImmersiveFullscreenController's animations. When the | |
148 // ImmersiveFullscreenController's animations are disabled, some behavior is | |
149 // slightly different. In particular, the behavior is different when there | |
150 // is a transfer in which lock keeps the top-of-window views revealed (eg | |
151 // bubble keeps top-of-window views revealed -> mouse keeps top-of-window | |
152 // views revealed). It is necessary to temporarily enable the | |
153 // ImmersiveFullscreenController's animations to get the correct behavior in | |
154 // tests. | |
155 void SetAnimationsDisabled(bool disabled) { | |
156 controller_->animations_disabled_for_test_ = disabled; | |
157 // Force any in progress animations to finish. | |
158 if (disabled) | |
159 controller_->animation_->End(); | |
160 } | |
161 | |
162 // Attempt to reveal the top-of-window views via |modality|. | 147 // Attempt to reveal the top-of-window views via |modality|. |
163 // The top-of-window views can only be revealed via mouse hover or a gesture. | 148 // The top-of-window views can only be revealed via mouse hover or a gesture. |
164 void AttemptReveal(Modality modality) { | 149 void AttemptReveal(Modality modality) { |
165 ASSERT_NE(modality, MODALITY_TOUCH); | 150 ASSERT_NE(modality, MODALITY_TOUCH); |
166 AttemptRevealStateChange(true, modality); | 151 AttemptRevealStateChange(true, modality); |
167 } | 152 } |
168 | 153 |
169 // Attempt to unreveal the top-of-window views via |modality|. The | 154 // Attempt to unreveal the top-of-window views via |modality|. The |
170 // top-of-window views can be unrevealed via any modality. | 155 // top-of-window views can be unrevealed via any modality. |
171 void AttemptUnreveal(Modality modality) { | 156 void AttemptUnreveal(Modality modality) { |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 event_generator.ClickLeftButton(); | 376 event_generator.ClickLeftButton(); |
392 EXPECT_FALSE(controller()->IsRevealed()); | 377 EXPECT_FALSE(controller()->IsRevealed()); |
393 | 378 |
394 // Moving a lot below the top container ends a reveal. | 379 // Moving a lot below the top container ends a reveal. |
395 AttemptReveal(MODALITY_MOUSE); | 380 AttemptReveal(MODALITY_MOUSE); |
396 EXPECT_TRUE(controller()->IsRevealed()); | 381 EXPECT_TRUE(controller()->IsRevealed()); |
397 event_generator.MoveMouseTo(top_container_bounds_in_screen.x(), | 382 event_generator.MoveMouseTo(top_container_bounds_in_screen.x(), |
398 top_container_bounds_in_screen.bottom() + 50); | 383 top_container_bounds_in_screen.bottom() + 50); |
399 EXPECT_FALSE(controller()->IsRevealed()); | 384 EXPECT_FALSE(controller()->IsRevealed()); |
400 | 385 |
401 // The mouse position cannot cause a reveal when TopContainerView's widget | 386 // The mouse position cannot cause a reveal when the top container's widget |
402 // has capture. | 387 // has capture. |
403 views::Widget* widget = top_container()->GetWidget(); | 388 views::Widget* widget = top_container()->GetWidget(); |
404 widget->SetCapture(top_container()); | 389 widget->SetCapture(top_container()); |
405 AttemptReveal(MODALITY_MOUSE); | 390 AttemptReveal(MODALITY_MOUSE); |
406 EXPECT_FALSE(controller()->IsRevealed()); | 391 EXPECT_FALSE(controller()->IsRevealed()); |
407 widget->ReleaseCapture(); | 392 widget->ReleaseCapture(); |
408 | 393 |
409 // The mouse position cannot end the reveal while TopContainerView's widget | 394 // The mouse position cannot end the reveal while the top container's widget |
410 // has capture. | 395 // has capture. |
411 AttemptReveal(MODALITY_MOUSE); | 396 AttemptReveal(MODALITY_MOUSE); |
412 EXPECT_TRUE(controller()->IsRevealed()); | 397 EXPECT_TRUE(controller()->IsRevealed()); |
413 widget->SetCapture(top_container()); | 398 widget->SetCapture(top_container()); |
414 event_generator.MoveMouseTo(top_container_bounds_in_screen.x(), | 399 event_generator.MoveMouseTo(top_container_bounds_in_screen.x(), |
415 top_container_bounds_in_screen.bottom() + 51); | 400 top_container_bounds_in_screen.bottom() + 51); |
416 EXPECT_TRUE(controller()->IsRevealed()); | 401 EXPECT_TRUE(controller()->IsRevealed()); |
417 | 402 |
418 // Releasing capture should end the reveal. | 403 // Releasing capture should end the reveal. |
419 widget->ReleaseCapture(); | 404 widget->ReleaseCapture(); |
420 EXPECT_FALSE(controller()->IsRevealed()); | 405 EXPECT_FALSE(controller()->IsRevealed()); |
421 } | 406 } |
422 | 407 |
| 408 // Test mouse event processing for top-of-screen reveal triggering when the |
| 409 // top container's widget is inactive. |
| 410 TEST_F(ImmersiveFullscreenControllerTest, Inactive) { |
| 411 // Set up initial state. |
| 412 views::Widget* popup_widget = views::Widget::CreateWindowWithContextAndBounds( |
| 413 NULL, |
| 414 CurrentContext(), |
| 415 gfx::Rect(0, 0, 200, 200)); |
| 416 popup_widget->Show(); |
| 417 ASSERT_FALSE(top_container()->GetWidget()->IsActive()); |
| 418 |
| 419 controller()->SetEnabled(true); |
| 420 ASSERT_TRUE(controller()->IsEnabled()); |
| 421 ASSERT_FALSE(controller()->IsRevealed()); |
| 422 |
| 423 gfx::Rect top_container_bounds_in_screen = |
| 424 top_container()->GetBoundsInScreen(); |
| 425 gfx::Rect popup_bounds_in_screen = popup_widget->GetWindowBoundsInScreen(); |
| 426 ASSERT_EQ(top_container_bounds_in_screen.origin().ToString(), |
| 427 popup_bounds_in_screen.origin().ToString()); |
| 428 ASSERT_GT(top_container_bounds_in_screen.right(), |
| 429 popup_bounds_in_screen.right()); |
| 430 |
| 431 // The top-of-window views should stay hidden if the cursor is at the top edge |
| 432 // but above an obscured portion of the top-of-window views. |
| 433 MoveMouse(popup_bounds_in_screen.x(), |
| 434 top_container_bounds_in_screen.y()); |
| 435 EXPECT_FALSE(controller()->IsRevealed()); |
| 436 |
| 437 // The top-of-window views should reveal if the cursor is at the top edge and |
| 438 // above an unobscured portion of the top-of-window views. |
| 439 MoveMouse(top_container_bounds_in_screen.right() - 1, |
| 440 top_container_bounds_in_screen.y()); |
| 441 EXPECT_TRUE(controller()->IsRevealed()); |
| 442 |
| 443 // The top-of-window views should stay revealed if the cursor is moved off |
| 444 // of the top edge. |
| 445 MoveMouse(top_container_bounds_in_screen.right() - 1, |
| 446 top_container_bounds_in_screen.bottom() - 1); |
| 447 EXPECT_TRUE(controller()->IsRevealed()); |
| 448 |
| 449 // Moving way off of the top-of-window views should end the immersive reveal. |
| 450 MoveMouse(top_container_bounds_in_screen.right() - 1, |
| 451 top_container_bounds_in_screen.bottom() + 50); |
| 452 EXPECT_FALSE(controller()->IsRevealed()); |
| 453 |
| 454 // Moving way off of the top-of-window views in a region where the |
| 455 // top-of-window views are obscured should also end the immersive reveal. |
| 456 // Ideally, the immersive reveal would end immediately when the cursor moves |
| 457 // to an obscured portion of the top-of-window views. |
| 458 MoveMouse(top_container_bounds_in_screen.right() - 1, |
| 459 top_container_bounds_in_screen.y()); |
| 460 EXPECT_TRUE(controller()->IsRevealed()); |
| 461 MoveMouse(top_container_bounds_in_screen.x(), |
| 462 top_container_bounds_in_screen.bottom() + 50); |
| 463 EXPECT_FALSE(controller()->IsRevealed()); |
| 464 } |
| 465 |
423 // Test mouse event processing for top-of-screen reveal triggering when the user | 466 // Test mouse event processing for top-of-screen reveal triggering when the user |
424 // has a vertical display layout (primary display above/below secondary display) | 467 // has a vertical display layout (primary display above/below secondary display) |
425 // and the immersive fullscreen window is on the bottom display. | 468 // and the immersive fullscreen window is on the bottom display. |
426 TEST_F(ImmersiveFullscreenControllerTest, MouseEventsVerticalDisplayLayout) { | 469 TEST_F(ImmersiveFullscreenControllerTest, MouseEventsVerticalDisplayLayout) { |
427 if (!SupportsMultipleDisplays()) | 470 if (!SupportsMultipleDisplays()) |
428 return; | 471 return; |
429 | 472 |
430 // Set up initial state. | 473 // Set up initial state. |
431 UpdateDisplay("800x600,800x600"); | 474 UpdateDisplay("800x600,800x600"); |
432 ash::DisplayLayout display_layout(ash::DisplayLayout::TOP, 0); | 475 ash::DisplayLayout display_layout(ash::DisplayLayout::TOP, 0); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 | 531 |
489 // The top-of-window views should stay revealed if the user moves the mouse | 532 // The top-of-window views should stay revealed if the user moves the mouse |
490 // around in the bottom region of the secondary display. | 533 // around in the bottom region of the secondary display. |
491 event_generator.MoveMouseTo(x + 10, y_top_edge - 3); | 534 event_generator.MoveMouseTo(x + 10, y_top_edge - 3); |
492 EXPECT_TRUE(controller()->IsRevealed()); | 535 EXPECT_TRUE(controller()->IsRevealed()); |
493 | 536 |
494 // The top-of-window views should hide if the user moves the mouse away from | 537 // The top-of-window views should hide if the user moves the mouse away from |
495 // the bottom region of the secondary display. | 538 // the bottom region of the secondary display. |
496 event_generator.MoveMouseTo(x, y_top_edge - 20); | 539 event_generator.MoveMouseTo(x, y_top_edge - 20); |
497 EXPECT_FALSE(controller()->IsRevealed()); | 540 EXPECT_FALSE(controller()->IsRevealed()); |
| 541 |
| 542 // Test that it is possible to reveal the top-of-window views by overshooting |
| 543 // the top edge slightly when the top container's widget is not active. |
| 544 views::Widget* popup_widget = views::Widget::CreateWindowWithContextAndBounds( |
| 545 NULL, |
| 546 CurrentContext(), |
| 547 gfx::Rect(0, 200, 100, 100)); |
| 548 popup_widget->Show(); |
| 549 ASSERT_FALSE(top_container()->GetWidget()->IsActive()); |
| 550 ASSERT_FALSE(top_container()->GetBoundsInScreen().Intersects( |
| 551 popup_widget->GetWindowBoundsInScreen())); |
| 552 event_generator.MoveMouseTo(x, y_top_edge + 1); |
| 553 MoveMouse(x, y_top_edge - 2); |
| 554 EXPECT_TRUE(controller()->IsRevealed()); |
498 } | 555 } |
499 | 556 |
500 // Test behavior when the mouse becomes hovered without moving. | 557 // Test behavior when the mouse becomes hovered without moving. |
501 TEST_F(ImmersiveFullscreenControllerTest, MouseHoveredWithoutMoving) { | 558 TEST_F(ImmersiveFullscreenControllerTest, MouseHoveredWithoutMoving) { |
502 controller()->SetEnabled(true); | 559 controller()->SetEnabled(true); |
503 scoped_ptr<ImmersiveRevealedLock> lock; | 560 scoped_ptr<ImmersiveRevealedLock> lock; |
504 | 561 |
505 // 1) Test that if the mouse becomes hovered without the mouse moving due to a | 562 // 1) Test that if the mouse becomes hovered without the mouse moving due to a |
506 // lock causing the top-of-window views to be revealed (and the mouse | 563 // lock causing the top-of-window views to be revealed (and the mouse |
507 // happening to be near the top of the screen), the top-of-window views do not | 564 // happening to be near the top of the screen), the top-of-window views do not |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
669 scoped_ptr<ImmersiveRevealedLock> lock(controller()->GetRevealedLock( | 726 scoped_ptr<ImmersiveRevealedLock> lock(controller()->GetRevealedLock( |
670 ImmersiveFullscreenController::ANIMATE_REVEAL_NO)); | 727 ImmersiveFullscreenController::ANIMATE_REVEAL_NO)); |
671 EXPECT_FALSE(controller()->IsRevealed()); | 728 EXPECT_FALSE(controller()->IsRevealed()); |
672 unrelated_view->RequestFocus(); | 729 unrelated_view->RequestFocus(); |
673 controller()->SetEnabled(true); | 730 controller()->SetEnabled(true); |
674 EXPECT_TRUE(controller()->IsRevealed()); | 731 EXPECT_TRUE(controller()->IsRevealed()); |
675 lock.reset(); | 732 lock.reset(); |
676 EXPECT_FALSE(controller()->IsRevealed()); | 733 EXPECT_FALSE(controller()->IsRevealed()); |
677 } | 734 } |
678 | 735 |
679 // Test how activation affects whether the top-of-window views are revealed. | 736 // Test how transient windows affect whether the top-of-window views are |
680 // The behavior when a bubble is activated is tested in | 737 // revealed. |
681 // ImmersiveFullscreenControllerTest.Bubbles. | 738 TEST_F(ImmersiveFullscreenControllerTest, Transient) { |
682 TEST_F(ImmersiveFullscreenControllerTest, Activation) { | |
683 views::Widget* top_container_widget = top_container()->GetWidget(); | 739 views::Widget* top_container_widget = top_container()->GetWidget(); |
684 | 740 |
685 controller()->SetEnabled(true); | 741 controller()->SetEnabled(true); |
686 ASSERT_FALSE(controller()->IsRevealed()); | 742 ASSERT_FALSE(controller()->IsRevealed()); |
687 | 743 |
688 // 1) Test that a transient window which is not a bubble does not trigger a | 744 // 1) Test that a transient window which is not a bubble does not trigger a |
689 // reveal but does keep the top-of-window views revealed if they are already | 745 // reveal but does keep the top-of-window views revealed if they are already |
690 // revealed. | 746 // revealed. |
691 views::Widget::InitParams transient_params; | 747 views::Widget::InitParams transient_params; |
692 transient_params.ownership = | 748 transient_params.ownership = |
693 views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 749 views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
694 transient_params.parent = top_container_widget->GetNativeView(); | 750 transient_params.parent = top_container_widget->GetNativeView(); |
695 transient_params.bounds = gfx::Rect(0, 0, 100, 100); | 751 transient_params.bounds = gfx::Rect(0, 100, 100, 100); |
696 scoped_ptr<views::Widget> transient_widget(new views::Widget()); | 752 scoped_ptr<views::Widget> transient_widget(new views::Widget()); |
697 transient_widget->Init(transient_params); | 753 transient_widget->Init(transient_params); |
698 transient_widget->Show(); | |
699 | 754 |
700 EXPECT_FALSE(controller()->IsRevealed()); | 755 EXPECT_FALSE(controller()->IsRevealed()); |
701 top_container_widget->Activate(); | |
702 AttemptReveal(MODALITY_MOUSE); | 756 AttemptReveal(MODALITY_MOUSE); |
703 EXPECT_TRUE(controller()->IsRevealed()); | 757 EXPECT_TRUE(controller()->IsRevealed()); |
704 transient_widget->Activate(); | 758 transient_widget->Show(); |
705 SetHovered(false); | 759 SetHovered(false); |
706 EXPECT_TRUE(controller()->IsRevealed()); | 760 EXPECT_TRUE(controller()->IsRevealed()); |
707 transient_widget.reset(); | 761 transient_widget.reset(); |
708 EXPECT_FALSE(controller()->IsRevealed()); | 762 EXPECT_FALSE(controller()->IsRevealed()); |
709 | 763 |
710 // 2) Test that activating a non-transient window ends the reveal if any. | 764 // 2) Test that activating a non-transient window does not keep the |
| 765 // top-of-window views revealed. |
711 views::Widget::InitParams non_transient_params; | 766 views::Widget::InitParams non_transient_params; |
712 non_transient_params.ownership = | 767 non_transient_params.ownership = |
713 views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; | 768 views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET; |
714 non_transient_params.context = top_container_widget->GetNativeView(); | 769 non_transient_params.context = top_container_widget->GetNativeView(); |
715 non_transient_params.bounds = gfx::Rect(0, 0, 100, 100); | 770 non_transient_params.bounds = gfx::Rect(0, 100, 100, 100); |
716 scoped_ptr<views::Widget> non_transient_widget(new views::Widget()); | 771 scoped_ptr<views::Widget> non_transient_widget(new views::Widget()); |
717 non_transient_widget->Init(non_transient_params); | 772 non_transient_widget->Init(non_transient_params); |
718 non_transient_widget->Show(); | |
719 | 773 |
720 EXPECT_FALSE(controller()->IsRevealed()); | 774 EXPECT_FALSE(controller()->IsRevealed()); |
721 top_container_widget->Activate(); | |
722 AttemptReveal(MODALITY_MOUSE); | 775 AttemptReveal(MODALITY_MOUSE); |
723 EXPECT_TRUE(controller()->IsRevealed()); | 776 EXPECT_TRUE(controller()->IsRevealed()); |
724 non_transient_widget->Activate(); | 777 non_transient_widget->Show(); |
| 778 SetHovered(false); |
725 EXPECT_FALSE(controller()->IsRevealed()); | 779 EXPECT_FALSE(controller()->IsRevealed()); |
726 } | 780 } |
727 | 781 |
728 // Test how bubbles affect whether the top-of-window views are revealed. | 782 // Test how bubbles affect whether the top-of-window views are revealed. |
729 TEST_F(ImmersiveFullscreenControllerTest, Bubbles) { | 783 TEST_F(ImmersiveFullscreenControllerTest, Bubbles) { |
730 scoped_ptr<ImmersiveRevealedLock> revealed_lock; | 784 scoped_ptr<ImmersiveRevealedLock> revealed_lock; |
731 views::Widget* top_container_widget = top_container()->GetWidget(); | 785 views::Widget* top_container_widget = top_container()->GetWidget(); |
732 | 786 |
733 // Add views to the view hierarchy to which we will anchor bubbles. | 787 // Add views to the view hierarchy to which we will anchor bubbles. |
734 views::View* child_view = new views::View(); | 788 views::View* child_view = new views::View(); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
767 EXPECT_FALSE(controller()->IsRevealed()); | 821 EXPECT_FALSE(controller()->IsRevealed()); |
768 | 822 |
769 // 2) Test that transitioning from keeping the top-of-window views revealed | 823 // 2) Test that transitioning from keeping the top-of-window views revealed |
770 // because of a bubble to keeping the top-of-window views revealed because of | 824 // because of a bubble to keeping the top-of-window views revealed because of |
771 // mouse hover by activating |top_container_widget| works. | 825 // mouse hover by activating |top_container_widget| works. |
772 views::Widget* bubble_widget3 = views::BubbleDelegateView::CreateBubble( | 826 views::Widget* bubble_widget3 = views::BubbleDelegateView::CreateBubble( |
773 new views::BubbleDelegateView(child_view, views::BubbleBorder::NONE)); | 827 new views::BubbleDelegateView(child_view, views::BubbleBorder::NONE)); |
774 bubble_widget3->Show(); | 828 bubble_widget3->Show(); |
775 SetHovered(true); | 829 SetHovered(true); |
776 EXPECT_TRUE(controller()->IsRevealed()); | 830 EXPECT_TRUE(controller()->IsRevealed()); |
777 | |
778 SetAnimationsDisabled(false); | |
779 // Activating |top_container_widget| will close |bubble_widget3|. | |
780 top_container_widget->Activate(); | 831 top_container_widget->Activate(); |
781 SetAnimationsDisabled(true); | |
782 EXPECT_TRUE(controller()->IsRevealed()); | 832 EXPECT_TRUE(controller()->IsRevealed()); |
783 | 833 |
784 // 3) Test that the top-of-window views stay revealed as long as at least one | 834 // 3) Test that the top-of-window views stay revealed as long as at least one |
785 // bubble anchored to a child of the top container is visible. | 835 // bubble anchored to a child of the top container is visible. |
786 SetHovered(false); | 836 SetHovered(false); |
787 EXPECT_FALSE(controller()->IsRevealed()); | 837 EXPECT_FALSE(controller()->IsRevealed()); |
788 | 838 |
789 views::BubbleDelegateView* bubble_delegate4(new views::BubbleDelegateView( | 839 views::BubbleDelegateView* bubble_delegate4(new views::BubbleDelegateView( |
790 child_view, views::BubbleBorder::NONE)); | 840 child_view, views::BubbleBorder::NONE)); |
791 bubble_delegate4->set_use_focusless(true); | 841 bubble_delegate4->set_use_focusless(true); |
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
890 // Disabling immersive fullscreen maintains the user's auto-hide selection. | 940 // Disabling immersive fullscreen maintains the user's auto-hide selection. |
891 controller()->SetEnabled(false); | 941 controller()->SetEnabled(false); |
892 window()->SetProperty(aura::client::kShowStateKey, | 942 window()->SetProperty(aura::client::kShowStateKey, |
893 ui::SHOW_STATE_NORMAL); | 943 ui::SHOW_STATE_NORMAL); |
894 EXPECT_EQ(ash::SHELF_AUTO_HIDE, shelf->visibility_state()); | 944 EXPECT_EQ(ash::SHELF_AUTO_HIDE, shelf->visibility_state()); |
895 } | 945 } |
896 | 946 |
897 } // namespase ash | 947 } // namespase ash |
898 | 948 |
899 #endif // defined(OS_CHROMEOS) | 949 #endif // defined(OS_CHROMEOS) |
OLD | NEW |