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

Side by Side Diff: ash/shelf/shelf_layout_manager_unittest.cc

Issue 2576913002: Use mojo app list interfaces for mash and classic ash. (Closed)
Patch Set: Sync and rebase Created 3 years, 11 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
« no previous file with comments | « ash/mus/window_manager.cc ('k') | ash/shelf/shelf_view_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 "ash/common/shelf/shelf_layout_manager.h" 5 #include "ash/common/shelf/shelf_layout_manager.h"
6 6
7 #include "ash/aura/wm_shelf_aura.h" 7 #include "ash/aura/wm_shelf_aura.h"
8 #include "ash/aura/wm_window_aura.h" 8 #include "ash/aura/wm_window_aura.h"
9 #include "ash/common/accelerators/accelerator_controller.h" 9 #include "ash/common/accelerators/accelerator_controller.h"
10 #include "ash/common/accelerators/accelerator_table.h" 10 #include "ash/common/accelerators/accelerator_table.h"
11 #include "ash/common/focus_cycler.h" 11 #include "ash/common/focus_cycler.h"
12 #include "ash/common/material_design/material_design_controller.h" 12 #include "ash/common/material_design/material_design_controller.h"
13 #include "ash/common/session/session_state_delegate.h" 13 #include "ash/common/session/session_state_delegate.h"
14 #include "ash/common/shelf/shelf_constants.h" 14 #include "ash/common/shelf/shelf_constants.h"
15 #include "ash/common/shelf/shelf_layout_manager_observer.h" 15 #include "ash/common/shelf/shelf_layout_manager_observer.h"
16 #include "ash/common/shelf/shelf_view.h" 16 #include "ash/common/shelf/shelf_view.h"
17 #include "ash/common/shelf/shelf_widget.h" 17 #include "ash/common/shelf/shelf_widget.h"
18 #include "ash/common/shelf/wm_shelf.h" 18 #include "ash/common/shelf/wm_shelf.h"
19 #include "ash/common/system/status_area_widget.h" 19 #include "ash/common/system/status_area_widget.h"
20 #include "ash/common/system/tray/system_tray.h" 20 #include "ash/common/system/tray/system_tray.h"
21 #include "ash/common/system/tray/system_tray_item.h" 21 #include "ash/common/system/tray/system_tray_item.h"
22 #include "ash/common/wm/window_state.h" 22 #include "ash/common/wm/window_state.h"
23 #include "ash/common/wm_shell.h" 23 #include "ash/common/wm_shell.h"
24 #include "ash/public/cpp/shell_window_ids.h" 24 #include "ash/public/cpp/shell_window_ids.h"
25 #include "ash/root_window_controller.h" 25 #include "ash/root_window_controller.h"
26 #include "ash/shell.h" 26 #include "ash/shell.h"
27 #include "ash/test/ash_test_base.h" 27 #include "ash/test/ash_test_base.h"
28 #include "ash/test/test_app_list_view_presenter_impl.h"
28 #include "ash/test/test_system_tray_item.h" 29 #include "ash/test/test_system_tray_item.h"
29 #include "ash/wm/window_state_aura.h" 30 #include "ash/wm/window_state_aura.h"
30 #include "ash/wm/window_util.h" 31 #include "ash/wm/window_util.h"
31 #include "base/command_line.h" 32 #include "base/command_line.h"
32 #include "base/run_loop.h" 33 #include "base/run_loop.h"
33 #include "ui/aura/client/aura_constants.h" 34 #include "ui/aura/client/aura_constants.h"
34 #include "ui/aura/client/window_parenting_client.h" 35 #include "ui/aura/client/window_parenting_client.h"
35 #include "ui/aura/window.h" 36 #include "ui/aura/window.h"
36 #include "ui/aura/window_event_dispatcher.h" 37 #include "ui/aura/window_event_dispatcher.h"
37 #include "ui/base/ui_base_switches.h" 38 #include "ui/base/ui_base_switches.h"
(...skipping 902 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 941
941 // Trying to activate the status should fail, since we only allow activating 942 // Trying to activate the status should fail, since we only allow activating
942 // it when the user is using the keyboard (i.e. through FocusCycler). 943 // it when the user is using the keyboard (i.e. through FocusCycler).
943 GetShelfWidget()->status_area_widget()->Activate(); 944 GetShelfWidget()->status_area_widget()->Activate();
944 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState()); 945 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());
945 946
946 GetShelfWidget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD); 947 GetShelfWidget()->GetFocusCycler()->RotateFocus(FocusCycler::FORWARD);
947 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); 948 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
948 } 949 }
949 950
950 // Makes sure shelf will be visible when app list opens as shelf is in 951 // Ensure a SHELF_VISIBLE shelf stays visible when the app list is shown.
951 // SHELF_VISIBLE state,and toggling app list won't change shelf
952 // visibility state.
953 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfVisibleState) { 952 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfVisibleState) {
954 WmShell* shell = WmShell::Get();
955 WmShelf* shelf = GetPrimaryShelf(); 953 WmShelf* shelf = GetPrimaryShelf();
956 ShelfLayoutManager* layout_manager = GetShelfLayoutManager();
957 layout_manager->LayoutShelf();
958 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER); 954 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_NEVER);
959 955
960 // Create a normal unmaximized window, shelf should be visible. 956 // The tested behavior relies on the app list presenter implementation.
957 test::TestAppListViewPresenterImpl app_list_presenter_impl;
958
959 // Create a normal unmaximized window; the shelf should be visible.
961 aura::Window* window = CreateTestWindow(); 960 aura::Window* window = CreateTestWindow();
962 window->SetBounds(gfx::Rect(0, 0, 100, 100)); 961 window->SetBounds(gfx::Rect(0, 0, 100, 100));
963 window->Show(); 962 window->Show();
964 EXPECT_FALSE(shell->GetAppListTargetVisibility()); 963 EXPECT_FALSE(app_list_presenter_impl.GetTargetVisibility());
965 EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState()); 964 EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());
966 965
967 // Show app list and the shelf stays visible. 966 // Show the app list and the shelf stays visible.
968 shell->ShowAppList(); 967 app_list_presenter_impl.Show(display_manager()->first_display_id());
969 EXPECT_TRUE(shell->GetAppListTargetVisibility()); 968 EXPECT_TRUE(app_list_presenter_impl.GetTargetVisibility());
970 EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState()); 969 EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());
971 970
972 // Hide app list and the shelf stays visible. 971 // Hide the app list and the shelf stays visible.
973 shell->DismissAppList(); 972 app_list_presenter_impl.Dismiss();
974 EXPECT_FALSE(shell->GetAppListTargetVisibility()); 973 EXPECT_FALSE(app_list_presenter_impl.GetTargetVisibility());
975 EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState()); 974 EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());
976 } 975 }
977 976
978 // Makes sure shelf will be shown with SHELF_AUTO_HIDE_SHOWN state 977 // Ensure a SHELF_AUTO_HIDE shelf is shown temporarily (SHELF_AUTO_HIDE_SHOWN)
979 // when app list opens as shelf is in SHELF_AUTO_HIDE state, and 978 // when the app list is shown, but the visibility state doesn't change.
980 // toggling app list won't change shelf visibility state.
981 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfAutoHideState) { 979 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfAutoHideState) {
982 WmShell* shell = WmShell::Get();
983 WmShelf* shelf = GetPrimaryShelf(); 980 WmShelf* shelf = GetPrimaryShelf();
984 ShelfLayoutManager* layout_manager = GetShelfLayoutManager();
985 layout_manager->LayoutShelf();
986 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 981 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
987 982
988 EXPECT_FALSE(shell->GetAppListTargetVisibility()); 983 // The tested behavior relies on the app list presenter implementation.
984 test::TestAppListViewPresenterImpl app_list_presenter_impl;
985
986 // Create a normal unmaximized window; the shelf should be hidden.
987 aura::Window* window = CreateTestWindow();
988 window->SetBounds(gfx::Rect(0, 0, 100, 100));
989 window->Show();
990 EXPECT_FALSE(app_list_presenter_impl.GetTargetVisibility());
991 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
992 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());
993
994 // Show the app list and the shelf should be temporarily visible.
995 app_list_presenter_impl.Show(display_manager()->first_display_id());
996 // The shelf's auto hide state won't be changed until the timer fires, so
997 // force it to update now.
998 GetShelfLayoutManager()->UpdateVisibilityState();
999 EXPECT_TRUE(app_list_presenter_impl.GetTargetVisibility());
989 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState()); 1000 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
990 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); 1001 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
991 1002
992 // Show app list. 1003 // Hide the app list and the shelf should be hidden again.
993 shell->ShowAppList(); 1004 app_list_presenter_impl.Dismiss();
994 // The shelf's auto hide state won't be changed until the timer fires, so 1005 EXPECT_FALSE(app_list_presenter_impl.GetTargetVisibility());
995 // force it to update now.
996 layout_manager->UpdateVisibilityState();
997 EXPECT_TRUE(shell->GetAppListTargetVisibility());
998 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState()); 1006 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
999 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState()); 1007 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf->GetAutoHideState());
1000
1001 // Hide app list.
1002 shell->DismissAppList();
1003 EXPECT_FALSE(shell->GetAppListTargetVisibility());
1004 EXPECT_EQ(SHELF_AUTO_HIDE, shelf->GetVisibilityState());
1005 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf->GetAutoHideState());
1006 } 1008 }
1007 1009
1008 // Makes sure that when we have dual displays, with one or both shelves are set 1010 // Makes sure that when we have dual displays, with one or both shelves are set
1009 // to AutoHide, viewing the AppList on one of them doesn't unhide the other 1011 // to AutoHide, viewing the AppList on one of them doesn't unhide the other
1010 // hidden shelf. 1012 // hidden shelf.
1011 TEST_F(ShelfLayoutManagerTest, DualDisplayOpenAppListWithShelfAutoHideState) { 1013 TEST_F(ShelfLayoutManagerTest, DualDisplayOpenAppListWithShelfAutoHideState) {
1012 if (!SupportsMultipleDisplays()) 1014 if (!SupportsMultipleDisplays())
1013 return; 1015 return;
1014 1016
1015 // Create two displays. 1017 // Create two displays.
(...skipping 20 matching lines...) Expand all
1036 aura::Window* window_2 = CreateTestWindowInParent(root_windows[1]); 1038 aura::Window* window_2 = CreateTestWindowInParent(root_windows[1]);
1037 window_2->SetBounds(gfx::Rect(201, 0, 100, 100)); 1039 window_2->SetBounds(gfx::Rect(201, 0, 100, 100));
1038 window_2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED); 1040 window_2->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_MAXIMIZED);
1039 window_2->Show(); 1041 window_2->Show();
1040 1042
1041 EXPECT_EQ(shelf_1->GetWindow()->GetRootWindow(), 1043 EXPECT_EQ(shelf_1->GetWindow()->GetRootWindow(),
1042 WmWindowAura::Get(window_1)->GetRootWindow()); 1044 WmWindowAura::Get(window_1)->GetRootWindow());
1043 EXPECT_EQ(shelf_2->GetWindow()->GetRootWindow(), 1045 EXPECT_EQ(shelf_2->GetWindow()->GetRootWindow(),
1044 WmWindowAura::Get(window_2)->GetRootWindow()); 1046 WmWindowAura::Get(window_2)->GetRootWindow());
1045 1047
1046 // Activate one window in one display and manually trigger the update of shelf 1048 // Activate one window in one display.
1047 // visibility.
1048 wm::ActivateWindow(window_1); 1049 wm::ActivateWindow(window_1);
1050
1051 // The tested behavior relies on the app list presenter implementation.
1052 test::TestAppListViewPresenterImpl app_list_presenter_impl;
1053
1049 Shell::GetInstance()->UpdateShelfVisibility(); 1054 Shell::GetInstance()->UpdateShelfVisibility();
1050 1055 EXPECT_FALSE(app_list_presenter_impl.GetTargetVisibility());
1051 EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility());
1052 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_1->GetVisibilityState()); 1056 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_1->GetVisibilityState());
1053 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_2->GetVisibilityState()); 1057 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_2->GetVisibilityState());
1054 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_1->GetAutoHideState()); 1058 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_1->GetAutoHideState());
1055 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_2->GetAutoHideState()); 1059 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_2->GetAutoHideState());
1056 1060
1057 // Show app list. 1061 // Show the app list; only the shelf on the same display should be shown.
1058 WmShell::Get()->ShowAppList(); 1062 app_list_presenter_impl.Show(display_manager()->first_display_id());
1059 Shell::GetInstance()->UpdateShelfVisibility(); 1063 Shell::GetInstance()->UpdateShelfVisibility();
1060 1064 EXPECT_TRUE(app_list_presenter_impl.GetTargetVisibility());
1061 // Only the shelf in the active display should be shown, the other is hidden.
1062 EXPECT_TRUE(WmShell::Get()->GetAppListTargetVisibility());
1063 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_1->GetVisibilityState()); 1065 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_1->GetVisibilityState());
1064 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf_1->GetAutoHideState()); 1066 EXPECT_EQ(SHELF_AUTO_HIDE_SHOWN, shelf_1->GetAutoHideState());
1065 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_2->GetVisibilityState()); 1067 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_2->GetVisibilityState());
1066 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_2->GetAutoHideState()); 1068 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_2->GetAutoHideState());
1067 1069
1068 // Hide app list, both shelves should be hidden. 1070 // Hide the app list, both shelves should be hidden.
1069 WmShell::Get()->DismissAppList(); 1071 app_list_presenter_impl.Dismiss();
1070 EXPECT_FALSE(WmShell::Get()->GetAppListTargetVisibility()); 1072 Shell::GetInstance()->UpdateShelfVisibility();
1073 EXPECT_FALSE(app_list_presenter_impl.GetTargetVisibility());
1071 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_1->GetVisibilityState()); 1074 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_1->GetVisibilityState());
1072 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_2->GetVisibilityState()); 1075 EXPECT_EQ(SHELF_AUTO_HIDE, shelf_2->GetVisibilityState());
1073 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_1->GetAutoHideState()); 1076 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_1->GetAutoHideState());
1074 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_2->GetAutoHideState()); 1077 EXPECT_EQ(SHELF_AUTO_HIDE_HIDDEN, shelf_2->GetAutoHideState());
1075 } 1078 }
1076 1079
1077 // Makes sure the shelf will be hidden when we have a fullscreen window, and it 1080 // Ensure a SHELF_HIDDEN shelf (for a fullscreen window) is shown temporarily
1078 // will unhide when we open the app list. 1081 // when the app list is shown, and hidden again when the app list is dismissed.
1079 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfHiddenState) { 1082 TEST_F(ShelfLayoutManagerTest, OpenAppListWithShelfHiddenState) {
1080 WmShell* shell = WmShell::Get();
1081 WmShelf* shelf = GetPrimaryShelf(); 1083 WmShelf* shelf = GetPrimaryShelf();
1082 ShelfLayoutManager* layout_manager = GetShelfLayoutManager();
1083 // For shelf to be visible, app list is not open in initial state.
1084 layout_manager->LayoutShelf();
1085 1084
1086 // Create a window and make it full screen. 1085 // The tested behavior relies on the app list presenter implementation.
1086 test::TestAppListViewPresenterImpl app_list_presenter_impl;
1087
1088 // Create a window and make it full screen; the shelf should be hidden.
1087 aura::Window* window = CreateTestWindow(); 1089 aura::Window* window = CreateTestWindow();
1088 window->SetBounds(gfx::Rect(0, 0, 100, 100)); 1090 window->SetBounds(gfx::Rect(0, 0, 100, 100));
1089 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN); 1091 window->SetProperty(aura::client::kShowStateKey, ui::SHOW_STATE_FULLSCREEN);
1090 window->Show(); 1092 window->Show();
1091 wm::ActivateWindow(window); 1093 wm::ActivateWindow(window);
1092 1094 EXPECT_FALSE(app_list_presenter_impl.GetTargetVisibility());
1093 // App list and shelf is not shown.
1094 EXPECT_FALSE(shell->GetAppListTargetVisibility());
1095 EXPECT_EQ(SHELF_HIDDEN, shelf->GetVisibilityState()); 1095 EXPECT_EQ(SHELF_HIDDEN, shelf->GetVisibilityState());
1096 1096
1097 // Show app list. 1097 // Show the app list and the shelf should be temporarily visible.
1098 shell->ShowAppList(); 1098 app_list_presenter_impl.Show(display_manager()->first_display_id());
1099 EXPECT_TRUE(shell->GetAppListTargetVisibility()); 1099 EXPECT_TRUE(app_list_presenter_impl.GetTargetVisibility());
1100 EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState()); 1100 EXPECT_EQ(SHELF_VISIBLE, shelf->GetVisibilityState());
1101 1101
1102 // Hide app list. 1102 // Hide the app list and the shelf should be hidden again.
1103 shell->DismissAppList(); 1103 app_list_presenter_impl.Dismiss();
1104 EXPECT_FALSE(shell->GetAppListTargetVisibility()); 1104 EXPECT_FALSE(app_list_presenter_impl.GetTargetVisibility());
1105 EXPECT_EQ(SHELF_HIDDEN, shelf->GetVisibilityState()); 1105 EXPECT_EQ(SHELF_HIDDEN, shelf->GetVisibilityState());
1106 } 1106 }
1107 1107
1108 // Tests the correct behavior of the shelf when there is a system modal window 1108 // Tests the correct behavior of the shelf when there is a system modal window
1109 // open when we have a single display. 1109 // open when we have a single display.
1110 TEST_F(ShelfLayoutManagerTest, ShelfWithSystemModalWindowSingleDisplay) { 1110 TEST_F(ShelfLayoutManagerTest, ShelfWithSystemModalWindowSingleDisplay) {
1111 WmShelf* shelf = GetPrimaryShelf(); 1111 WmShelf* shelf = GetPrimaryShelf();
1112 ShelfLayoutManager* layout_manager = GetShelfLayoutManager(); 1112 ShelfLayoutManager* layout_manager = GetShelfLayoutManager();
1113 layout_manager->LayoutShelf(); 1113 layout_manager->LayoutShelf();
1114 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS); 1114 shelf->SetAutoHideBehavior(SHELF_AUTO_HIDE_BEHAVIOR_ALWAYS);
(...skipping 734 matching lines...) Expand 10 before | Expand all | Expand 10 after
1849 // Open keyboard in sticky mode. 1849 // Open keyboard in sticky mode.
1850 kb_controller->ShowKeyboard(true); 1850 kb_controller->ShowKeyboard(true);
1851 layout_manager->OnKeyboardBoundsChanging(keyboard_bounds()); 1851 layout_manager->OnKeyboardBoundsChanging(keyboard_bounds());
1852 1852
1853 // Work area should be changed. 1853 // Work area should be changed.
1854 EXPECT_NE(orig_work_area, 1854 EXPECT_NE(orig_work_area,
1855 display::Screen::GetScreen()->GetPrimaryDisplay().work_area()); 1855 display::Screen::GetScreen()->GetPrimaryDisplay().work_area());
1856 } 1856 }
1857 1857
1858 } // namespace ash 1858 } // namespace ash
OLDNEW
« no previous file with comments | « ash/mus/window_manager.cc ('k') | ash/shelf/shelf_view_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698