diff options
author | Torne (Richard Coles) <torne@google.com> | 2014-11-12 17:59:43 +0000 |
---|---|---|
committer | Torne (Richard Coles) <torne@google.com> | 2014-11-12 17:59:43 +0000 |
commit | 1850ca92fc5c5faa2907b3befcf40067265148cc (patch) | |
tree | 7d10585f25356b3ee63b5ab4255161fe27725ee4 /athena | |
parent | e9e1f6521e4fef99aa1a1928c70ef3dfb55a8d9e (diff) | |
download | chromium_org-1850ca92fc5c5faa2907b3befcf40067265148cc.tar.gz |
Merge from Chromium at DEPS revision 03655fd3f6d7
This commit was generated by merge_to_master.py.
Change-Id: Ifba5396691b9164ba027be04398f7bc8e938750d
Diffstat (limited to 'athena')
46 files changed, 1067 insertions, 1252 deletions
diff --git a/athena/athena.gyp b/athena/athena.gyp index 25dafb0164..c47515666f 100644 --- a/athena/athena.gyp +++ b/athena/athena.gyp @@ -25,6 +25,7 @@ '../ui/aura/aura.gyp:aura_test_support', '../ui/chromeos/ui_chromeos.gyp:ui_chromeos', '../ui/display/display.gyp:display', + '../ui/events/devices/events_devices.gyp:events_devices', '../ui/events/events.gyp:events_base', '../ui/strings/ui_strings.gyp:ui_strings', '../ui/views/views.gyp:views', @@ -55,8 +56,6 @@ 'env/public/athena_env.h', 'home/app_list_view_delegate.cc', 'home/app_list_view_delegate.h', - 'home/athena_start_page_view.cc', - 'home/athena_start_page_view.h', 'home/home_card_constants.cc', 'home/home_card_constants.h', 'home/home_card_gesture_manager.cc', @@ -130,11 +129,14 @@ 'dependencies': [ 'athena_lib', '../base/third_party/dynamic_annotations/dynamic_annotations.gyp:dynamic_annotations', + '../components/components.gyp:app_modal_dialogs', + '../components/components.gyp:constrained_window', '../components/components.gyp:component_metrics_proto', '../components/components.gyp:omnibox', '../components/components.gyp:renderer_context_menu', '../components/components.gyp:web_modal', '../content/content.gyp:content_browser', + '../extensions/components/extensions_components.gyp:javascript_dialog_extensions_client', '../extensions/components/extensions_components.gyp:native_app_window', '../extensions/extensions.gyp:extensions_browser', '../extensions/extensions.gyp:extensions_common', @@ -172,6 +174,10 @@ 'extensions/athena_app_delegate_base.h', 'extensions/athena_app_window_client_base.cc', 'extensions/athena_app_window_client_base.h', + 'extensions/athena_constrained_window_views_client.cc', + 'extensions/athena_constrained_window_views_client.h', + 'extensions/athena_javascript_native_dialog_factory.cc', + 'extensions/athena_javascript_native_dialog_factory.h', 'extensions/athena_native_app_window_views.cc', 'extensions/athena_native_app_window_views.h', 'extensions/extension_app_model_builder.cc', @@ -277,11 +283,49 @@ 'test/base/test_resource_manager_delegate.cc', 'test/base/test_windows.cc', 'test/base/test_windows.h', + 'test/base/test_util.cc', + 'test/base/test_util.h', 'wm/test/window_manager_impl_test_api.cc', 'wm/test/window_manager_impl_test_api.h', ], }, { + 'target_name': 'athena_browsertest_support', + 'type': 'static_library', + 'dependencies': [ + '../testing/gtest.gyp:gtest', + 'athena_test_support', + 'main/athena_main.gyp:athena_main_lib', + 'resources/athena_resources.gyp:athena_pak', + ], + 'sources': [ + 'test/base/activity_lifetime_tracker.h', + 'test/base/activity_lifetime_tracker.cc', + 'test/base/athena_browser_test.h', + 'test/base/athena_browser_test.cc', + 'test/base/athena_browser_test.h', + 'test/base/athena_test_launcher_delegate.cc', + 'test/base/athena_test_launcher_delegate.h', + ], + }, + { + 'target_name': 'athena_browsertests', + 'type': 'executable', + 'dependencies': [ + '../testing/gtest.gyp:gtest', + '../skia/skia.gyp:skia', + 'athena_browsertest_support', + 'athena_app_shell_lib', + 'athena_lib', + ], + 'defines': [ + 'HAS_OUT_OF_PROC_TEST_RUNNER', + ], + 'sources': [ + 'test/base/athena_browser_test_main.cc', + ], + }, + { 'target_name': 'athena_unittests', 'type': 'executable', 'dependencies': [ @@ -297,7 +341,6 @@ 'activity/activity_manager_unittest.cc', 'content/app_activity_unittest.cc', 'env/athena_env_unittest.cc', - 'home/athena_start_page_view_unittest.cc', 'home/home_card_gesture_manager_unittest.cc', 'home/home_card_unittest.cc', 'input/accelerator_manager_unittest.cc', diff --git a/athena/content/DEPS b/athena/content/DEPS index f5ed971132..5fc372e507 100644 --- a/athena/content/DEPS +++ b/athena/content/DEPS @@ -6,6 +6,7 @@ include_rules = [ "+athena/resource_manager/public", "+athena/strings/grit/athena_strings.h", "+athena/wm/public", + "+components/app_modal_dialogs", "+components/favicon_base", "+components/metrics/proto", "+components/omnibox", diff --git a/athena/content/app_activity_browsertest.cc b/athena/content/app_activity_browsertest.cc index 17cc893d5c..2c954efba3 100644 --- a/athena/content/app_activity_browsertest.cc +++ b/athena/content/app_activity_browsertest.cc @@ -5,8 +5,8 @@ #include "athena/activity/public/activity.h" #include "athena/resource_manager/public/resource_manager.h" #include "athena/test/base/activity_lifetime_tracker.h" -#include "athena/test/chrome/athena_app_browsertest.h" -#include "athena/test/chrome/test_util.h" +#include "athena/test/base/test_util.h" +#include "athena/test/chrome/athena_app_browser_test.h" #include "athena/wm/public/window_list_provider.h" #include "athena/wm/public/window_manager.h" #include "base/strings/utf_string_conversions.h" @@ -72,9 +72,7 @@ class AppActivityBrowserTest : public AthenaAppBrowserTest { // Then a web activity (which will then be in front of the app). *web_activity = test_util::CreateTestWebActivity( - test_util::GetBrowserContext(), - base::UTF8ToUTF16("App1"), - GURL(kTestUrl)); + GetBrowserContext(), base::UTF8ToUTF16("App1"), GURL(kTestUrl)); ASSERT_TRUE(*web_activity); EXPECT_EQ(*web_activity, tracker_->GetNewActivityAndReset()); EXPECT_EQ(nullptr, tracker_->GetDeletedActivityAndReset()); @@ -124,10 +122,8 @@ IN_PROC_BROWSER_TEST_F(AppActivityBrowserTest, StartApplication) { // Test that creating an application (without a particular activity order // location) should activate it initially. IN_PROC_BROWSER_TEST_F(AppActivityBrowserTest, CreatedAppGetsFocus) { - Activity* web_activity = - test_util::CreateTestWebActivity(test_util::GetBrowserContext(), - base::UTF8ToUTF16("App1"), - GURL(kTestUrl)); + Activity* web_activity = test_util::CreateTestWebActivity( + GetBrowserContext(), base::UTF8ToUTF16("App1"), GURL(kTestUrl)); EXPECT_TRUE(IsActivityActive(web_activity)); Activity* app_activity = CreateTestAppActivity(GetTestAppID()); diff --git a/athena/content/chrome/web_activity_browsertest.cc b/athena/content/chrome/web_activity_browsertest.cc index 42f6d13170..aabe44919d 100644 --- a/athena/content/chrome/web_activity_browsertest.cc +++ b/athena/content/chrome/web_activity_browsertest.cc @@ -4,8 +4,8 @@ #include "athena/activity/public/activity.h" #include "athena/resource_manager/public/resource_manager.h" -#include "athena/test/chrome/athena_browsertest.h" -#include "athena/test/chrome/test_util.h" +#include "athena/test/base/test_util.h" +#include "athena/test/chrome/athena_chrome_browser_test.h" #include "athena/wm/public/window_list_provider.h" #include "athena/wm/public/window_manager.h" #include "base/strings/utf_string_conversions.h" @@ -21,16 +21,14 @@ namespace { const char kTestUrl[] = "chrome:about"; } -typedef AthenaBrowserTest WebActivityBrowserTest; +typedef AthenaChromeBrowserTest WebActivityBrowserTest; // A simple test to create web content. IN_PROC_BROWSER_TEST_F(WebActivityBrowserTest, SimpleCreate) { const GURL target_url(kTestUrl); // Create an activity, wait until it is loaded and check that it was created. Activity* activity = test_util::CreateTestWebActivity( - test_util::GetBrowserContext(), - base::UTF8ToUTF16("App"), - target_url); + GetBrowserContext(), base::UTF8ToUTF16("App"), target_url); ASSERT_TRUE(activity); EXPECT_NE(Activity::ACTIVITY_UNLOADED, activity->GetCurrentState()); // The activity manager should take care of destroying the activity upon @@ -47,16 +45,12 @@ IN_PROC_BROWSER_TEST_F(WebActivityBrowserTest, LoadUnloadReload) { // Create an activity (and wait until it is loaded). // The size of its overview image should be empty since it is visible. Activity* activity2 = test_util::CreateTestWebActivity( - test_util::GetBrowserContext(), - base::UTF8ToUTF16("App2"), - target_url); + GetBrowserContext(), base::UTF8ToUTF16("App2"), target_url); EXPECT_TRUE(activity2); EXPECT_EQ(list[0], activity2->GetWindow()); EXPECT_NE(Activity::ACTIVITY_UNLOADED, activity2->GetCurrentState()); Activity* activity1 = test_util::CreateTestWebActivity( - test_util::GetBrowserContext(), - base::UTF8ToUTF16("App1"), - target_url); + GetBrowserContext(), base::UTF8ToUTF16("App1"), target_url); EXPECT_TRUE(activity1); // |activity2| should now be the second activity. Both activities should have diff --git a/athena/content/chrome/web_activity_helpers_browsertest.cc b/athena/content/chrome/web_activity_helpers_browsertest.cc index 4dd8bee593..9dfdb0179c 100644 --- a/athena/content/chrome/web_activity_helpers_browsertest.cc +++ b/athena/content/chrome/web_activity_helpers_browsertest.cc @@ -3,8 +3,8 @@ // found in the LICENSE file. #include "athena/activity/public/activity.h" -#include "athena/test/chrome/athena_browsertest.h" -#include "athena/test/chrome/test_util.h" +#include "athena/test/base/test_util.h" +#include "athena/test/chrome/athena_chrome_browser_test.h" #include "base/strings/utf_string_conversions.h" #include "chrome/browser/extensions/tab_helper.h" #include "content/public/browser/notification_observer.h" @@ -58,7 +58,7 @@ class HelpersCreatedChecker : public content::NotificationObserver { DISALLOW_COPY_AND_ASSIGN(HelpersCreatedChecker); }; -typedef AthenaBrowserTest WebActivityHelpersBrowserTest; +typedef AthenaChromeBrowserTest WebActivityHelpersBrowserTest; // Test that the WebActivity helpers are attached to the web contents prior to // the RenderView view being created. This is important because some of the @@ -70,10 +70,8 @@ IN_PROC_BROWSER_TEST_F(WebActivityHelpersBrowserTest, CreationTime) { HelpersCreatedChecker checker; GURL url("http://www.google.com"); - athena::Activity* activity = - test_util::CreateTestWebActivity(test_util::GetBrowserContext(), - base::UTF8ToUTF16("App"), - url); + athena::Activity* activity = test_util::CreateTestWebActivity( + GetBrowserContext(), base::UTF8ToUTF16("App"), url); content::WebContents* web_contents1 = activity->GetWebContents(); EXPECT_NE(Activity::ACTIVITY_UNLOADED, activity->GetCurrentState()); EXPECT_TRUE(web_contents1->GetRenderViewHost()->IsRenderViewLive()); diff --git a/athena/content/content_proxy_browsertest.cc b/athena/content/content_proxy_browsertest.cc index c9628378a8..f48eed56d6 100644 --- a/athena/content/content_proxy_browsertest.cc +++ b/athena/content/content_proxy_browsertest.cc @@ -5,8 +5,8 @@ #include "athena/activity/public/activity.h" #include "athena/activity/public/activity_view_model.h" #include "athena/resource_manager/public/resource_manager.h" -#include "athena/test/chrome/athena_browsertest.h" -#include "athena/test/chrome/test_util.h" +#include "athena/test/base/test_util.h" +#include "athena/test/chrome/athena_chrome_browser_test.h" #include "base/command_line.h" #include "base/strings/utf_string_conversions.h" #include "ui/compositor/compositor_switches.h" @@ -22,7 +22,7 @@ const char kTestUrl[] = "chrome:about"; } // Need to override the test class to make the test always draw its content. -class ContentProxyBrowserTest : public AthenaBrowserTest { +class ContentProxyBrowserTest : public AthenaChromeBrowserTest { public: ContentProxyBrowserTest() {} ~ContentProxyBrowserTest() override {} @@ -31,7 +31,7 @@ class ContentProxyBrowserTest : public AthenaBrowserTest { void SetUpCommandLine(base::CommandLine* command_line) override { // Make sure that we draw the output - it's required for this test. command_line->AppendSwitch(switches::kEnablePixelOutputInTests); - AthenaBrowserTest::SetUpCommandLine(command_line); + AthenaChromeBrowserTest::SetUpCommandLine(command_line); } private: @@ -42,7 +42,7 @@ IN_PROC_BROWSER_TEST_F(ContentProxyBrowserTest, CreateContent) { const int kTimeoutMS = 12000; // The timeout: 2 seconds. const int kIterationSleepMS = 5; // The wait time in ms per iteration. const GURL gurl(kTestUrl); - content::BrowserContext* context = test_util::GetBrowserContext(); + content::BrowserContext* context = GetBrowserContext(); // Create an activity (and wait until it is loaded). // The size of its overview image should be empty since it is visible. Activity* activity1 = diff --git a/athena/content/web_activity.cc b/athena/content/web_activity.cc index d6801b84a6..a6bdb82b51 100644 --- a/athena/content/web_activity.cc +++ b/athena/content/web_activity.cc @@ -16,6 +16,7 @@ #include "base/bind.h" #include "base/command_line.h" #include "base/strings/utf_string_conversions.h" +#include "components/app_modal_dialogs/javascript_dialog_manager.h" #include "components/favicon_base/select_favicon_frames.h" #include "content/public/browser/native_web_keyboard_event.h" #include "content/public/browser/navigation_controller.h" @@ -365,8 +366,7 @@ class AthenaWebView : public views::WebView { } content::JavaScriptDialogManager* GetJavaScriptDialogManager() override { - NOTIMPLEMENTED(); - return nullptr; + return GetJavaScriptDialogManagerInstance(); } content::ColorChooser* OpenColorChooser( diff --git a/athena/env/DEPS b/athena/env/DEPS index bcac64e2dd..82dec51d6e 100644 --- a/athena/env/DEPS +++ b/athena/env/DEPS @@ -4,6 +4,7 @@ include_rules = [ "+ui/base", "+ui/chromeos", "+ui/display", + "+ui/events/devices", "+ui/gfx", "+ui/wm", ] diff --git a/athena/env/athena_env_impl.cc b/athena/env/athena_env_impl.cc index 326b950cc5..6b5975d7cf 100644 --- a/athena/env/athena_env_impl.cc +++ b/athena/env/athena_env_impl.cc @@ -22,6 +22,9 @@ #include "ui/display/chromeos/display_configurator.h" #include "ui/display/types/display_mode.h" #include "ui/display/types/display_snapshot.h" +#include "ui/events/devices/device_data_manager.h" +#include "ui/events/devices/input_device_event_observer.h" +#include "ui/events/devices/touchscreen_device.h" #include "ui/gfx/screen.h" #include "ui/wm/core/compound_event_filter.h" #include "ui/wm/core/cursor_manager.h" @@ -39,6 +42,48 @@ AthenaEnv* instance = nullptr; // Screen object used during shutdown. gfx::Screen* screen_for_shutdown = nullptr; +gfx::Transform GetTouchTransform(const ui::DisplaySnapshot& display, + const ui::TouchscreenDevice& touchscreen, + const gfx::SizeF& framebuffer_size) { + if (!display.current_mode()) + return gfx::Transform(); + + gfx::SizeF display_size = display.current_mode()->size(); +#if defined(USE_X11) + gfx::SizeF touchscreen_size = framebuffer_size; +#elif defined(USE_OZONE) + gfx::SizeF touchscreen_size = touchscreen.size; +#endif + + if (display_size.IsEmpty() || touchscreen_size.IsEmpty()) + return gfx::Transform(); + + gfx::Transform transform; + transform.Scale(display_size.width() / touchscreen_size.width(), + display_size.height() / touchscreen_size.height()); + + return transform; +} + +double GetTouchRadiusScale(const ui::DisplaySnapshot& display, + const ui::TouchscreenDevice& touchscreen, + const gfx::SizeF& framebuffer_size) { + if (!display.current_mode()) + return 1; + + gfx::SizeF display_size = display.current_mode()->size(); +#if defined(USE_X11) + gfx::SizeF touchscreen_size = framebuffer_size; +#elif defined(USE_OZONE) + gfx::SizeF touchscreen_size = touchscreen.size; +#endif + + if (display_size.IsEmpty() || touchscreen_size.IsEmpty()) + return 1; + + return std::sqrt(display_size.GetArea() / touchscreen_size.GetArea()); +} + // TODO(flackr:oshima): Remove this once athena switches to share // ash::DisplayManager. class ScreenForShutdown : public gfx::Screen { @@ -152,13 +197,16 @@ class AthenaNativeCursorManager : public wm::NativeCursorManager { class AthenaEnvImpl : public AthenaEnv, public aura::WindowTreeHostObserver, - public ui::DisplayConfigurator::Observer { + public ui::DisplayConfigurator::Observer, + public ui::InputDeviceEventObserver { public: AthenaEnvImpl() : display_configurator_(new ui::DisplayConfigurator) { display_configurator_->Init(false); display_configurator_->ForceInitialConfigure(0); display_configurator_->AddObserver(this); + ui::DeviceDataManager::GetInstance()->AddObserver(this); + gfx::Size screen_size = GetPrimaryDisplaySize(); if (screen_size.IsEmpty()) { // TODO(oshima): Remove this hack. @@ -234,6 +282,8 @@ class AthenaEnvImpl : public AthenaEnv, screen_.reset(); aura::Env::DeleteInstance(); + ui::DeviceDataManager::GetInstance()->RemoveObserver(this); + display_configurator_->RemoveObserver(this); display_configurator_.reset(); } @@ -286,11 +336,20 @@ class AthenaEnvImpl : public AthenaEnv, void OnDisplayModeChanged( const std::vector<ui::DisplayConfigurator::DisplayState>& displays) override { + MapTouchscreenToDisplay(); + gfx::Size size = GetPrimaryDisplaySize(); if (!size.IsEmpty()) host_->UpdateRootWindowSize(size); } + // ui::InputDeviceEventObserver: + void OnTouchscreenDeviceConfigurationChanged() override { + MapTouchscreenToDisplay(); + } + + void OnKeyboardDeviceConfigurationChanged() override {} + // aura::WindowTreeHostObserver: void OnHostCloseRequested(const aura::WindowTreeHost* host) override { base::MessageLoopForUI::current()->PostTask( @@ -306,6 +365,29 @@ class AthenaEnvImpl : public AthenaEnv, return mode ? mode->size() : gfx::Size(); } + void MapTouchscreenToDisplay() const { + auto device_manager = ui::DeviceDataManager::GetInstance(); + auto displays = display_configurator_->cached_displays(); + auto touchscreens = device_manager->touchscreen_devices(); + + if (displays.empty() || touchscreens.empty()) + return; + + gfx::SizeF framebuffer_size = display_configurator_->framebuffer_size(); + device_manager->ClearTouchTransformerRecord(); + device_manager->UpdateTouchInfoForDisplay( + displays[0].display->display_id(), + touchscreens[0].id, + GetTouchTransform(*displays[0].display, + touchscreens[0], + framebuffer_size)); + device_manager->UpdateTouchRadiusScale( + touchscreens[0].id, + GetTouchRadiusScale(*displays[0].display, + touchscreens[0], + framebuffer_size)); + } + scoped_ptr<aura::TestScreen> screen_; scoped_ptr<aura::WindowTreeHost> host_; diff --git a/athena/extensions/DEPS b/athena/extensions/DEPS index 84b22ffdf7..9de66a692c 100644 --- a/athena/extensions/DEPS +++ b/athena/extensions/DEPS @@ -3,9 +3,14 @@ include_rules = [ "+athena/activity/public", "+athena/home/public", "+athena/wm/public", + "+components/app_modal_dialogs", + "+components/constrained_window", + "+components/web_modal", "+content/public/browser", "+extensions/browser", "+extensions/common", + "+extensions/components/app_modal_dialogs", + "+extensions/components/javascript_dialog_extensions_client", "+extensions/components/native_app_window", "+extensions/grit", "+ui/app_list", diff --git a/athena/extensions/athena_constrained_window_views_client.cc b/athena/extensions/athena_constrained_window_views_client.cc new file mode 100644 index 0000000000..db818f68f2 --- /dev/null +++ b/athena/extensions/athena_constrained_window_views_client.cc @@ -0,0 +1,139 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "athena/extensions/athena_constrained_window_views_client.h" + +#include "athena/activity/public/activity.h" +#include "athena/activity/public/activity_manager.h" +#include "base/memory/scoped_ptr.h" +#include "base/observer_list.h" +#include "components/constrained_window/constrained_window_views.h" +#include "components/constrained_window/constrained_window_views_client.h" +#include "components/web_modal/web_contents_modal_dialog_host.h" +#include "extensions/browser/guest_view/guest_view_base.h" +#include "ui/aura/window.h" +#include "ui/aura/window_observer.h" +#include "ui/aura/window_property.h" + +namespace athena { +namespace { + +// Provides the host envrionment for web modal dialogs. See +// web_modal::WebContentsModalDialogHost, and ModalDialogHost for more +// details. +class ModalDialogHostImpl : public web_modal::WebContentsModalDialogHost, + public aura::WindowObserver { + public: + // Returns a modal dialog host for |window|. If it doesn't exist it creates + // one and stores it as owned property. + static ModalDialogHost* Get(aura::Window* window); + + private: + explicit ModalDialogHostImpl(aura::Window* host_window) + : host_window_(host_window) { + host_window_->AddObserver(this); + } + ~ModalDialogHostImpl() override {} + + // web_modal::ModalDialogHost: + gfx::NativeView GetHostView() const override { + return host_window_; + } + gfx::Point GetDialogPosition(const gfx::Size& size) override { + gfx::Rect host_bounds = host_window_->GetBoundsInScreen(); + host_bounds.ClampToCenteredSize(size); + return host_bounds.origin(); + } + void AddObserver(web_modal::ModalDialogHostObserver* observer) override { + observer_list_.AddObserver(observer); + } + void RemoveObserver(web_modal::ModalDialogHostObserver* observer) override { + observer_list_.RemoveObserver(observer); + } + + // web_modal::WebContensModalDialogHost: + gfx::Size GetMaximumDialogSize() override { + return host_window_->bounds().size(); + } + + // aura::WindowObserver: + void OnWindowDestroying(aura::Window* window) override { + if (window != host_window_) + return; + host_window_->RemoveObserver(this); + FOR_EACH_OBSERVER(web_modal::ModalDialogHostObserver, + observer_list_, + OnHostDestroying()); + } + void OnWindowBoundsChanged(aura::Window* window, + const gfx::Rect& old_bounds, + const gfx::Rect& new_bounds) override { + if (window != host_window_) + return; + FOR_EACH_OBSERVER(web_modal::ModalDialogHostObserver, + observer_list_, + OnPositionRequiresUpdate()); + } + + aura::Window* host_window_; + ObserverList<web_modal::ModalDialogHostObserver> observer_list_; + + DISALLOW_COPY_AND_ASSIGN(ModalDialogHostImpl); +}; + +// A window property key to store the modal dialog host for +// dialogs created with the window as its parent. +DEFINE_OWNED_WINDOW_PROPERTY_KEY(web_modal::ModalDialogHost, + kModalDialogHostKey, + nullptr); + +// static +web_modal::ModalDialogHost* ModalDialogHostImpl::Get( + aura::Window* window) { + web_modal::ModalDialogHost* host = window->GetProperty(kModalDialogHostKey); + if (!host) { + host = new ModalDialogHostImpl(window); + window->SetProperty(kModalDialogHostKey, host); + } + return host; +} + +class AthenaConstrainedWindowViewsClient + : public ConstrainedWindowViewsClient { + public: + AthenaConstrainedWindowViewsClient() {} + ~AthenaConstrainedWindowViewsClient() override {} + + private: + // ConstrainedWindowViewsClient: + content::WebContents* GetEmbedderWebContents( + content::WebContents* initiator_web_contents) override { + extensions::GuestViewBase* guest_view = + extensions::GuestViewBase::FromWebContents(initiator_web_contents); + return guest_view && guest_view->embedder_web_contents() ? + guest_view->embedder_web_contents() : initiator_web_contents; + } + web_modal::ModalDialogHost* GetModalDialogHost( + gfx::NativeWindow parent) override { + Activity* activity = ActivityManager::Get()->GetActivityForWindow(parent); + if (activity) + return ModalDialogHostImpl::Get(parent); + return nullptr; + } + + DISALLOW_COPY_AND_ASSIGN(AthenaConstrainedWindowViewsClient); +}; + +} // namespace + +void InstallConstrainedWindowViewsClient() { + SetConstrainedWindowViewsClient( + make_scoped_ptr(new AthenaConstrainedWindowViewsClient)); +} + +void UninstallConstrainedWindowViewsClient() { + SetConstrainedWindowViewsClient(nullptr); +} + +} // namespace athena diff --git a/athena/extensions/athena_constrained_window_views_client.h b/athena/extensions/athena_constrained_window_views_client.h new file mode 100644 index 0000000000..4c5b0bb62f --- /dev/null +++ b/athena/extensions/athena_constrained_window_views_client.h @@ -0,0 +1,15 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ATHENA_EXTENSIONS_ATHENA_CONSTRAINED_WINDOW_VIEWS_CLIENT_H_ +#define ATHENA_EXTENSIONS_ATHENA_CONSTRAINED_WINDOW_VIEWS_CLIENT_H_ + +namespace athena { + +void InstallConstrainedWindowViewsClient(); +void UninstallConstrainedWindowViewsClient(); + +} // namespace athena + +#endif // ATHENA_EXTENSIONS_ATHENA_CONSTRAINED_WINDOW_VIEWS_CLIENT_H_ diff --git a/athena/extensions/athena_javascript_native_dialog_factory.cc b/athena/extensions/athena_javascript_native_dialog_factory.cc new file mode 100644 index 0000000000..6883a9e536 --- /dev/null +++ b/athena/extensions/athena_javascript_native_dialog_factory.cc @@ -0,0 +1,46 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "athena/extensions/athena_javascript_native_dialog_factory.h" + +#include "base/memory/scoped_ptr.h" +#include "components/app_modal_dialogs/javascript_dialog_manager.h" +#include "components/app_modal_dialogs/javascript_native_dialog_factory.h" +#include "components/app_modal_dialogs/views/javascript_app_modal_dialog_views.h" +#include "components/constrained_window/constrained_window_views.h" + +class JavaScriptAppModalDialog; +class NativeAppModalDialog; + +namespace athena { +namespace { + +class AthenaJavaScriptNativeDialogFactory + : public JavaScriptNativeDialogFactory { + public: + AthenaJavaScriptNativeDialogFactory() {} + ~AthenaJavaScriptNativeDialogFactory() override {} + + private: + // JavScriptNativeDialogFactory: + NativeAppModalDialog* CreateNativeJavaScriptDialog( + JavaScriptAppModalDialog* dialog, + gfx::NativeWindow parent_window) override{ + JavaScriptAppModalDialogViews* d = + new JavaScriptAppModalDialogViews(dialog); + CreateBrowserModalDialogViews(d, parent_window); + return d; + } + + DISALLOW_COPY_AND_ASSIGN(AthenaJavaScriptNativeDialogFactory); +}; + +} // namespace + +void InstallJavaScriptNativeDialogFactory() { + SetJavaScriptNativeDialogFactory( + make_scoped_ptr(new AthenaJavaScriptNativeDialogFactory)); +} + +} // namespace athena diff --git a/athena/extensions/athena_javascript_native_dialog_factory.h b/athena/extensions/athena_javascript_native_dialog_factory.h new file mode 100644 index 0000000000..8792dc84bf --- /dev/null +++ b/athena/extensions/athena_javascript_native_dialog_factory.h @@ -0,0 +1,14 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ATHENA_EXTENSIONS_ATHENA_JAVASCRIPT_NATIVE_DIALOG_FACTORY_H_ +#define ATHENA_EXTENSIONS_ATHENA_JAVASCRIPT_NATIVE_DIALOG_FACTORY_H_ + +namespace athena { + +void InstallJavaScriptNativeDialogFactory(); + +} // namespace + +#endif // ATHENA_EXTENSIONS_ATHENA_JAVASCRIPT_NATIVE_DIALOG_FACTORY_H_ diff --git a/athena/extensions/extensions_delegate.cc b/athena/extensions/extensions_delegate.cc index a5c39b9162..00a93b96d9 100644 --- a/athena/extensions/extensions_delegate.cc +++ b/athena/extensions/extensions_delegate.cc @@ -4,7 +4,10 @@ #include "athena/extensions/public/extensions_delegate.h" +#include "athena/extensions/athena_constrained_window_views_client.h" +#include "athena/extensions/athena_javascript_native_dialog_factory.h" #include "base/logging.h" +#include "extensions/components/javascript_dialog_extensions_client/javascript_dialog_extension_client_impl.h" namespace athena { namespace { @@ -14,11 +17,15 @@ ExtensionsDelegate* instance = nullptr; } // namespace ExtensionsDelegate::ExtensionsDelegate() { + InstallConstrainedWindowViewsClient(); + InstallJavaScriptDialogExtensionsClient(); + InstallJavaScriptNativeDialogFactory(); DCHECK(!instance); instance = this; } ExtensionsDelegate::~ExtensionsDelegate() { + UninstallConstrainedWindowViewsClient(); DCHECK(instance); instance = nullptr; } diff --git a/athena/home/app_list_view_delegate.cc b/athena/home/app_list_view_delegate.cc index eead245f10..270aae6b32 100644 --- a/athena/home/app_list_view_delegate.cc +++ b/athena/home/app_list_view_delegate.cc @@ -22,10 +22,6 @@ #include "ui/app_list/search_result.h" #include "ui/app_list/speech_ui_model.h" #include "ui/base/l10n/l10n_util.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/gfx/image/image_skia.h" -#include "ui/resources/grit/ui_resources.h" -#include "ui/views/controls/image_view.h" namespace athena { @@ -144,14 +140,7 @@ void AppListViewDelegate::ShowForProfileByPath( views::View* AppListViewDelegate::CreateStartPageWebView( const gfx::Size& size) { - // A static image of the logo. This needs to support dynamic Doodles - // eventually. - views::ImageView* logo_image = new views::ImageView(); - logo_image->SetImage(ui::ResourceBundle::GetSharedInstance(). - GetImageSkiaNamed(IDR_LOCAL_NTP_IMAGES_LOGO_PNG)); - logo_image->SetHorizontalAlignment(views::ImageView::CENTER); - logo_image->SetVerticalAlignment(views::ImageView::CENTER); - return logo_image; + return nullptr; } std::vector<views::View*> AppListViewDelegate::CreateCustomPageWebViews( diff --git a/athena/home/athena_start_page_view.cc b/athena/home/athena_start_page_view.cc deleted file mode 100644 index bb78ec2bc8..0000000000 --- a/athena/home/athena_start_page_view.cc +++ /dev/null @@ -1,476 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "athena/home/athena_start_page_view.h" - -#include "athena/home/home_card_constants.h" -#include "athena/system/public/system_ui.h" -#include "base/bind.h" -#include "base/strings/string_util.h" -#include "third_party/skia/include/core/SkPaint.h" -#include "third_party/skia/include/core/SkPath.h" -#include "ui/app_list/app_list_item.h" -#include "ui/app_list/app_list_item_list.h" -#include "ui/app_list/app_list_model.h" -#include "ui/app_list/app_list_view_delegate.h" -#include "ui/app_list/search_box_model.h" -#include "ui/app_list/views/search_box_view.h" -#include "ui/app_list/views/search_result_list_view.h" -#include "ui/compositor/closure_animation_observer.h" -#include "ui/compositor/scoped_layer_animation_settings.h" -#include "ui/gfx/canvas.h" -#include "ui/views/background.h" -#include "ui/views/border.h" -#include "ui/views/controls/textfield/textfield.h" -#include "ui/views/layout/box_layout.h" -#include "ui/views/layout/fill_layout.h" -#include "ui/views/round_rect_painter.h" - -namespace { - -const size_t kMaxIconNum = 3; -const int kIconSize = 50; -const int kIconMargin = 25; - -const int kTopMargin = 100; - -// Copied from ui/app_list/views/start_page_view.cc -const int kInstantContainerSpacing = 20; -const int kWebViewWidth = 500; -const int kWebViewHeight = 105; -const int kSearchBoxBorderWidth = 1; -const int kSearchBoxCornerRadius = 2; - -// Taken from the mock. The width is not specified by pixel but the search box -// covers 6 icons with margin. -const int kSearchBoxWidth = kIconSize * 6 + kIconMargin * 7; -const int kSearchBoxHeight = 40; - -gfx::Size GetIconContainerSize() { - return gfx::Size(kIconSize * kMaxIconNum + kIconMargin * (kMaxIconNum - 1), - kIconSize); -} - -class PlaceHolderButton : public views::ImageButton, - public views::ButtonListener { - public: - PlaceHolderButton() - : ImageButton(this) { - gfx::Canvas canvas(gfx::Size(kIconSize, kIconSize), 1.0f, true); - SkPaint paint; - paint.setStyle(SkPaint::kFill_Style); - paint.setColor(SkColorSetRGB(86, 119, 252)); - paint.setFlags(SkPaint::kAntiAlias_Flag); - canvas.DrawCircle( - gfx::Point(kIconSize / 2, kIconSize / 2), kIconSize / 2, paint); - - scoped_ptr<gfx::ImageSkia> image( - new gfx::ImageSkia(canvas.ExtractImageRep())); - SetImage(STATE_NORMAL, image.get()); - } - - private: - // views::ButtonListener: - void ButtonPressed(views::Button* sender, const ui::Event& event) override { - // Do nothing: remove these place holders. - } - - DISALLOW_COPY_AND_ASSIGN(PlaceHolderButton); -}; - -class AppIconButton : public views::ImageButton, - public views::ButtonListener { - public: - explicit AppIconButton(app_list::AppListItem* item) - : ImageButton(this), item_(nullptr) { - SetItem(item); - } - - void SetItem(app_list::AppListItem* item) { - item_ = item; - // TODO(mukai): icon should be resized. - SetImage(STATE_NORMAL, &item->icon()); - } - - private: - // views::ButtonListener: - void ButtonPressed(views::Button* sender, const ui::Event& event) override { - DCHECK_EQ(sender, this); - item_->Activate(event.flags()); - } - - app_list::AppListItem* item_; - - DISALLOW_COPY_AND_ASSIGN(AppIconButton); -}; - -// The background to paint the round rectangle of the view area. -class RoundRectBackground : public views::Background { - public: - RoundRectBackground(SkColor color, int corner_radius) - : color_(color), - corner_radius_(corner_radius) {} - ~RoundRectBackground() override {} - - private: - // views::Background: - void Paint(gfx::Canvas* canvas, views::View* view) const override { - SkPaint paint; - paint.setStyle(SkPaint::kFill_Style); - paint.setColor(color_); - canvas->DrawRoundRect(view->GetContentsBounds(), corner_radius_, paint); - } - - SkColor color_; - int corner_radius_; - - DISALLOW_COPY_AND_ASSIGN(RoundRectBackground); -}; - -class SearchBoxContainer : public views::View { - public: - explicit SearchBoxContainer(app_list::SearchBoxView* search_box) - : search_box_(search_box) { - search_box->set_background( - new RoundRectBackground(SK_ColorWHITE, kSearchBoxCornerRadius)); - search_box->SetBorder(views::Border::CreateBorderPainter( - new views::RoundRectPainter(SK_ColorGRAY, kSearchBoxCornerRadius), - gfx::Insets(kSearchBoxBorderWidth, kSearchBoxBorderWidth, - kSearchBoxBorderWidth, kSearchBoxBorderWidth))); - SetLayoutManager(new views::FillLayout()); - AddChildView(search_box_); - } - ~SearchBoxContainer() override {} - - private: - // views::View: - gfx::Size GetPreferredSize() const override { - return gfx::Size(kSearchBoxWidth, kSearchBoxHeight); - } - - // Owned by the views hierarchy. - app_list::SearchBoxView* search_box_; - - DISALLOW_COPY_AND_ASSIGN(SearchBoxContainer); -}; - -} // namespace - -namespace athena { - -// static -const char AthenaStartPageView::kViewClassName[] = "AthenaStartPageView"; - -AthenaStartPageView::LayoutData::LayoutData() - : system_info_opacity(1.0f), logo_opacity(1.0f) { -} - -AthenaStartPageView::AthenaStartPageView( - app_list::AppListViewDelegate* view_delegate) - : delegate_(view_delegate), - layout_state_(0.0f), - weak_factory_(this) { - system_info_view_ = - SystemUI::Get()->CreateSystemInfoView(SystemUI::COLOR_SCHEME_DARK); - system_info_view_->SetPaintToLayer(true); - system_info_view_->SetFillsBoundsOpaquely(false); - AddChildView(system_info_view_); - - logo_ = view_delegate->CreateStartPageWebView( - gfx::Size(kWebViewWidth, kWebViewHeight)); - logo_->SetPaintToLayer(true); - logo_->SetFillsBoundsOpaquely(false); - logo_->SetSize(gfx::Size(kWebViewWidth, kWebViewHeight)); - AddChildView(logo_); - - search_results_view_ = - new app_list::SearchResultListView(nullptr, view_delegate); - // search_results_view_'s size will shrink after settings results. - search_results_height_ = static_cast<views::View*>( - search_results_view_)->GetHeightForWidth(kSearchBoxWidth); - search_results_view_->SetResults(view_delegate->GetModel()->results()); - - search_results_view_->SetVisible(false); - search_results_view_->SetPaintToLayer(true); - search_results_view_->SetFillsBoundsOpaquely(false); - AddChildView(search_results_view_); - - app_icon_container_ = new views::View(); - AddChildView(app_icon_container_); - app_icon_container_->SetPaintToLayer(true); - app_icon_container_->layer()->SetFillsBoundsOpaquely(false); - app_icon_container_->SetLayoutManager(new views::BoxLayout( - views::BoxLayout::kHorizontal, 0, 0, kIconMargin)); - app_icon_container_->SetSize(GetIconContainerSize()); - UpdateAppIcons(); - view_delegate->GetModel()->top_level_item_list()->AddObserver(this); - - control_icon_container_ = new views::View(); - control_icon_container_->SetPaintToLayer(true); - control_icon_container_->SetFillsBoundsOpaquely(false); - AddChildView(control_icon_container_); - control_icon_container_->SetLayoutManager(new views::BoxLayout( - views::BoxLayout::kHorizontal, 0, 0, kIconMargin)); - for (size_t i = 0; i < kMaxIconNum; ++i) - control_icon_container_->AddChildView(new PlaceHolderButton()); - control_icon_container_->SetSize(GetIconContainerSize()); - - search_box_view_ = new app_list::SearchBoxView(this, view_delegate); - search_box_view_->set_contents_view(this); - search_box_view_->search_box()->set_id(kHomeCardSearchBoxId); - search_box_container_ = new SearchBoxContainer(search_box_view_); - search_box_container_->SetPaintToLayer(true); - search_box_container_->SetFillsBoundsOpaquely(false); - search_box_container_->SetSize(search_box_container_->GetPreferredSize()); - AddChildView(search_box_container_); -} - -AthenaStartPageView::~AthenaStartPageView() { - delegate_->GetModel()->top_level_item_list()->RemoveObserver(this); -} - -void AthenaStartPageView::RequestFocusOnSearchBox() { - search_box_view_->search_box()->RequestFocus(); -} - -void AthenaStartPageView::SetLayoutState(float layout_state) { - layout_state_ = layout_state; - Layout(); - FOR_EACH_OBSERVER(Observer, observers_, OnLayoutStateChanged(layout_state)); -} - -void AthenaStartPageView::SetLayoutStateWithAnimation( - float layout_state, - gfx::Tween::Type tween_type) { - ui::ScopedLayerAnimationSettings system_info( - system_info_view_->layer()->GetAnimator()); - ui::ScopedLayerAnimationSettings logo(logo_->layer()->GetAnimator()); - ui::ScopedLayerAnimationSettings search_box( - search_box_container_->layer()->GetAnimator()); - ui::ScopedLayerAnimationSettings icons( - app_icon_container_->layer()->GetAnimator()); - ui::ScopedLayerAnimationSettings controls( - control_icon_container_->layer()->GetAnimator()); - - system_info.SetTweenType(tween_type); - logo.SetTweenType(tween_type); - search_box.SetTweenType(tween_type); - icons.SetTweenType(tween_type); - controls.SetTweenType(tween_type); - - SetLayoutState(layout_state); -} - -void AthenaStartPageView::AddObserver(AthenaStartPageView::Observer* observer) { - observers_.AddObserver(observer); -} - -void AthenaStartPageView::RemoveObserver( - AthenaStartPageView::Observer* observer) { - observers_.RemoveObserver(observer); -} - -AthenaStartPageView::LayoutData AthenaStartPageView::CreateBottomBounds( - int width) { - LayoutData state; - state.icons.set_size(app_icon_container_->size()); - state.icons.set_x(kIconMargin); - state.icons.set_y(kIconMargin); - - state.controls.set_size(control_icon_container_->size()); - state.controls.set_x(width - kIconMargin - state.controls.width()); - state.controls.set_y(kIconMargin); - - int search_box_max_width = - state.controls.x() - state.icons.right() - kIconMargin * 2; - state.search_box.set_width(std::min(search_box_max_width, kSearchBoxWidth)); - state.search_box.set_height(search_box_container_->height()); - state.search_box.set_x((width - state.search_box.width()) / 2); - state.search_box.set_y((kHomeCardHeight - state.search_box.height()) / 2); - - state.system_info_opacity = 0.0f; - state.logo_opacity = 0.0f; - return state; -} - -AthenaStartPageView::LayoutData AthenaStartPageView::CreateCenteredBounds( - int width) { - LayoutData state; - - state.search_box.set_size(search_box_container_->GetPreferredSize()); - state.search_box.set_x((width - state.search_box.width()) / 2); - state.search_box.set_y(logo_->bounds().bottom() + kInstantContainerSpacing); - - state.icons.set_size(app_icon_container_->size()); - state.icons.set_x(width / 2 - state.icons.width() - kIconMargin / 2); - state.icons.set_y(state.search_box.bottom() + kInstantContainerSpacing); - - state.controls.set_size(control_icon_container_->size()); - state.controls.set_x(width / 2 + kIconMargin / 2 + kIconMargin % 2); - state.controls.set_y(state.icons.y()); - - state.system_info_opacity = 1.0f; - state.logo_opacity = 1.0f; - return state; -} - -void AthenaStartPageView::UpdateAppIcons() { - app_list::AppListItemList* top_level = - delegate_->GetModel()->top_level_item_list(); - size_t max_items = std::min(top_level->item_count(), kMaxIconNum); - for (size_t i = 0; i < max_items; ++i) { - if (i < static_cast<size_t>(app_icon_container_->child_count())) { - AppIconButton* button = - static_cast<AppIconButton*>(app_icon_container_->child_at(i)); - button->SetItem(top_level->item_at(i)); - } else { - app_icon_container_->AddChildView( - new AppIconButton(top_level->item_at(i))); - } - } - - while (max_items < static_cast<size_t>(app_icon_container_->child_count())) { - scoped_ptr<views::View> remover( - app_icon_container_->child_at(app_icon_container_->child_count() - 1)); - app_icon_container_->RemoveChildView(remover.get()); - } -} - -void AthenaStartPageView::LayoutSearchResults(bool should_show_search_results) { - if (should_show_search_results == - search_results_view_->layer()->GetTargetVisibility()) { - return; - } - if (should_show_search_results && layout_state_ != 1.0f) - SetLayoutState(1.0f); - - gfx::Rect search_box_bounds = search_box_container_->bounds(); - if (!search_results_view_->visible()) { - search_results_view_->SetVisible(true); - search_results_view_->SetBounds( - search_box_bounds.x(), search_box_bounds.bottom(), - search_box_bounds.width(), 0); - } - logo_->SetVisible(true); - - { - ui::ScopedLayerAnimationSettings logo_settings( - logo_->layer()->GetAnimator()); - logo_settings.SetTweenType(gfx::Tween::EASE_IN_OUT); - logo_settings.AddObserver(new ui::ClosureAnimationObserver( - base::Bind(&AthenaStartPageView::OnSearchResultLayoutAnimationCompleted, - weak_factory_.GetWeakPtr(), - should_show_search_results))); - - ui::ScopedLayerAnimationSettings search_box_settings( - search_box_container_->layer()->GetAnimator()); - search_box_settings.SetTweenType(gfx::Tween::EASE_IN_OUT); - - ui::ScopedLayerAnimationSettings search_results_settings( - search_results_view_->layer()->GetAnimator()); - search_results_settings.SetTweenType(gfx::Tween::EASE_IN_OUT); - - if (should_show_search_results) { - logo_->layer()->SetOpacity(0.0f); - search_box_bounds.set_y( - search_box_bounds.y() - search_results_height_ - - kInstantContainerSpacing); - search_box_container_->SetBoundsRect(search_box_bounds); - search_results_view_->SetBounds( - search_box_bounds.x(), - search_box_bounds.bottom() + kInstantContainerSpacing, - search_box_bounds.width(), - search_results_height_); - } else { - logo_->layer()->SetOpacity(1.0f); - search_box_bounds.set_y( - logo_->bounds().bottom() + kInstantContainerSpacing); - search_box_container_->SetBoundsRect(search_box_bounds); - - gfx::Rect search_results_bounds = search_results_view_->bounds(); - search_results_bounds.set_y(search_results_bounds.bottom()); - search_results_bounds.set_height(0); - search_results_view_->SetBoundsRect(search_results_bounds); - } - } -} - -void AthenaStartPageView::OnSearchResultLayoutAnimationCompleted( - bool should_show_search_results) { - logo_->SetVisible(!should_show_search_results); - search_results_view_->SetVisible(should_show_search_results); -} - -void AthenaStartPageView::Layout() { - search_results_view_->SetVisible(false); - - system_info_view_->SetBounds( - 0, 0, width(), system_info_view_->GetPreferredSize().height()); - - gfx::Rect logo_bounds(x() + width() / 2 - kWebViewWidth / 2, y() + kTopMargin, - kWebViewWidth, kWebViewHeight); - logo_->SetBoundsRect(logo_bounds); - - LayoutData bottom_bounds = CreateBottomBounds(width()); - LayoutData centered_bounds = CreateCenteredBounds(width()); - - system_info_view_->layer()->SetOpacity(gfx::Tween::FloatValueBetween( - gfx::Tween::CalculateValue(gfx::Tween::EASE_IN_2, layout_state_), - bottom_bounds.system_info_opacity, centered_bounds.system_info_opacity)); - system_info_view_->SetVisible( - system_info_view_->layer()->GetTargetOpacity() != 0.0f); - - logo_->layer()->SetOpacity(gfx::Tween::FloatValueBetween( - gfx::Tween::CalculateValue(gfx::Tween::EASE_IN_2, layout_state_), - bottom_bounds.logo_opacity, centered_bounds.logo_opacity)); - logo_->SetVisible(logo_->layer()->GetTargetOpacity() != 0.0f); - - app_icon_container_->SetBoundsRect(gfx::Tween::RectValueBetween( - layout_state_, bottom_bounds.icons, centered_bounds.icons)); - control_icon_container_->SetBoundsRect(gfx::Tween::RectValueBetween( - layout_state_, bottom_bounds.controls, centered_bounds.controls)); - search_box_container_->SetBoundsRect(gfx::Tween::RectValueBetween( - layout_state_, bottom_bounds.search_box, centered_bounds.search_box)); -} - -bool AthenaStartPageView::OnKeyPressed(const ui::KeyEvent& key_event) { - return search_results_view_->visible() && - search_results_view_->OnKeyPressed(key_event); -} - -void AthenaStartPageView::QueryChanged(app_list::SearchBoxView* sender) { - delegate_->StartSearch(); - - base::string16 query; - base::TrimWhitespace( - delegate_->GetModel()->search_box()->text(), base::TRIM_ALL, &query); - - if (!query.empty()) - search_results_view_->SetSelectedIndex(0); - - LayoutSearchResults(!query.empty()); -} - -void AthenaStartPageView::OnListItemAdded(size_t index, - app_list::AppListItem* item) { - UpdateAppIcons(); -} - -void AthenaStartPageView::OnListItemRemoved(size_t index, - app_list::AppListItem* item) { - UpdateAppIcons(); -} - -void AthenaStartPageView::OnListItemMoved(size_t from_index, - size_t to_index, - app_list::AppListItem* item) { - UpdateAppIcons(); -} - -// static -size_t AthenaStartPageView::GetMaxIconNumForTest() { - return kMaxIconNum; -} - -} // namespace athena diff --git a/athena/home/athena_start_page_view.h b/athena/home/athena_start_page_view.h deleted file mode 100644 index fd15dca207..0000000000 --- a/athena/home/athena_start_page_view.h +++ /dev/null @@ -1,128 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef ATHENA_HOME_ATHENA_START_PAGE_VIEW_H_ -#define ATHENA_HOME_ATHENA_START_PAGE_VIEW_H_ - -#include "athena/athena_export.h" -#include "base/memory/weak_ptr.h" -#include "base/observer_list.h" -#include "ui/app_list/app_list_item_list_observer.h" -#include "ui/app_list/views/search_box_view_delegate.h" -#include "ui/gfx/animation/tween.h" -#include "ui/views/view.h" - -namespace app_list { -class AppListModelObserver; -class AppListViewDelegate; -class SearchBoxView; -class SearchResultListView; -} - -namespace athena { - -class ATHENA_EXPORT AthenaStartPageView - : public views::View, - public app_list::SearchBoxViewDelegate, - public app_list::AppListItemListObserver { - public: - class Observer { - public: - virtual void OnLayoutStateChanged(float new_state) = 0; - }; - - explicit AthenaStartPageView(app_list::AppListViewDelegate* delegate); - ~AthenaStartPageView() override; - - // Requests the focus on the search box in the start page view. - void RequestFocusOnSearchBox(); - - // Updates the layout state. See the comment of |layout_state_| field. - void SetLayoutState(float layout_state); - - // Updates the layout state and move the subviews to the target location with - // animation. - void SetLayoutStateWithAnimation(float layout_state, - gfx::Tween::Type tween_type); - - void AddObserver(Observer* observer); - void RemoveObserver(Observer* observer); - - private: - friend class AthenaStartPageViewTest; - - static const char kViewClassName[]; - - static size_t GetMaxIconNumForTest(); - - // A struct which bundles the layout data of subviews. - struct LayoutData { - gfx::Rect search_box; - gfx::Rect icons; - gfx::Rect controls; - float system_info_opacity; - float logo_opacity; - - LayoutData(); - }; - - // Returns the bounds for |VISIBLE_BOTTOM|. - LayoutData CreateBottomBounds(int width); - - // Returns the bounds for |VISIBLE_CENTERED|. - LayoutData CreateCenteredBounds(int width); - - void UpdateAppIcons(); - - // Schedules the animation for the layout the search box and the search - // results. - void LayoutSearchResults(bool should_show_search_results); - - // Called when the animation of search box / search results layout has - // completed. - void OnSearchResultLayoutAnimationCompleted(bool should_show_search_results); - - // views::View: - void Layout() override; - bool OnKeyPressed(const ui::KeyEvent& key_event) override; - - // app_list::SearchBoxViewDelegate: - void QueryChanged(app_list::SearchBoxView* sender) override; - - // app_list::AppListItemListObserver: - void OnListItemAdded(size_t index, app_list::AppListItem* item) override; - void OnListItemRemoved(size_t index, app_list::AppListItem* item) override; - void OnListItemMoved(size_t from_index, - size_t to_index, - app_list::AppListItem* item) override; - - // Not owned. - app_list::AppListViewDelegate* delegate_; - - // Views are owned through its hierarchy. - views::View* system_info_view_; - views::View* app_icon_container_; - views::View* search_box_container_; - views::View* control_icon_container_; - views::View* logo_; - app_list::SearchBoxView* search_box_view_; - app_list::SearchResultListView* search_results_view_; - - // The expected height of |search_results_view_| - int search_results_height_; - - // The state to specify how each of the subviews should be laid out, in the - // range of [0, 1]. 0 means fully BOTTOM state, and 1 is fully CENTERED state. - float layout_state_; - - ObserverList<Observer> observers_; - - base::WeakPtrFactory<AthenaStartPageView> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(AthenaStartPageView); -}; - -} // namespace athena - -#endif // ATHENA_HOME_ATHENA_START_PAGE_VIEW_H_ diff --git a/athena/home/athena_start_page_view_unittest.cc b/athena/home/athena_start_page_view_unittest.cc deleted file mode 100644 index 9019999134..0000000000 --- a/athena/home/athena_start_page_view_unittest.cc +++ /dev/null @@ -1,279 +0,0 @@ -// Copyright 2014 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "athena/home/athena_start_page_view.h" - -#include "athena/home/home_card_constants.h" -#include "athena/test/base/athena_test_base.h" -#include "base/format_macros.h" -#include "base/strings/stringprintf.h" -#include "base/strings/utf_string_conversions.h" -#include "ui/app_list/app_list_switches.h" -#include "ui/app_list/search_box_model.h" -#include "ui/app_list/test/app_list_test_model.h" -#include "ui/app_list/test/app_list_test_view_delegate.h" -#include "ui/app_list/views/search_box_view.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/views/controls/textfield/textfield.h" - -namespace athena { - -class AthenaTestViewDelegate : public app_list::test::AppListTestViewDelegate { - public: - AthenaTestViewDelegate() {} - ~AthenaTestViewDelegate() override {} - - private: - // app_list::AppListViewDelegate: - views::View* CreateStartPageWebView(const gfx::Size& size) override { - return new views::View(); - } - - DISALLOW_COPY_AND_ASSIGN(AthenaTestViewDelegate); -}; - -class AthenaStartPageViewTest : public test::AthenaTestBase { - public: - AthenaStartPageViewTest() {} - ~AthenaStartPageViewTest() override {} - - // testing::Test: - void SetUp() override { - test::AthenaTestBase::SetUp(); - for (size_t i = 0; i < GetMaxIconNum(); ++i) - AddTestItem(i); - - view_.reset(new AthenaStartPageView(&view_delegate_)); - SetSize(gfx::Size(1280, 800)); - } - void TearDown() override { - view_.reset(); - test::AthenaTestBase::TearDown(); - } - - protected: - void SetSize(const gfx::Size& new_size) { - view_->SetSize(new_size); - view_->Layout(); - } - - void AddTestItem(size_t index) { - app_list::test::AppListTestModel* model = view_delegate_.GetTestModel(); - model->AddItem(new app_list::test::AppListTestModel::AppListTestItem( - GetAppIdFor(index), model)); - } - - static size_t GetMaxIconNum() { - return AthenaStartPageView::GetMaxIconNumForTest(); - } - - static std::string GetAppIdFor(size_t index) { - return base::StringPrintf("id-%" PRIuS, index); - } - - app_list::AppListModel* GetModel() { return view_delegate_.GetTestModel(); } - - views::View* GetIconsContainer() { return view_->app_icon_container_; } - - gfx::Rect GetIconsBounds() const { - return view_->app_icon_container_->layer()->GetTargetBounds(); - } - - gfx::Rect GetControlBounds() const { - return view_->control_icon_container_->layer()->GetTargetBounds(); - } - - gfx::Rect GetSearchBoxBounds() const { - return view_->search_box_container_->layer()->GetTargetBounds(); - } - - gfx::Rect GetLogoBounds() const { - return view_->logo_->layer()->GetTargetBounds(); - } - - bool IsLogoVisible() const { - return view_->logo_->layer()->GetTargetOpacity() > 0 && - view_->logo_->layer()->GetTargetVisibility(); - } - - gfx::Size GetSearchBoxPreferredSize() { - return view_->search_box_container_->GetPreferredSize(); - } - - void SetSearchQuery(const base::string16& query) { - view_delegate_.GetModel()->search_box()->SetText(query); - } - - base::string16 GetVisibleQuery() { - return view_->search_box_view_->search_box()->text(); - } - - float layout_state() { return view_->layout_state_; } - - scoped_ptr<AthenaStartPageView> view_; - - private: - AthenaTestViewDelegate view_delegate_; - - DISALLOW_COPY_AND_ASSIGN(AthenaStartPageViewTest); -}; - -TEST_F(AthenaStartPageViewTest, BasicLayout) { - // BOTTOM state. logo is invisible. icons, search box, and controls are - // arranged horizontally. - EXPECT_FALSE(IsLogoVisible()); - - // Three components are aligned at the middle point. - EXPECT_NEAR(GetIconsBounds().CenterPoint().y(), - GetControlBounds().CenterPoint().y(), - 1); - EXPECT_NEAR(GetIconsBounds().CenterPoint().y(), - GetSearchBoxBounds().CenterPoint().y(), - 1); - EXPECT_NEAR(GetControlBounds().CenterPoint().y(), - GetSearchBoxBounds().CenterPoint().y(), - 1); - - // Horizonttaly aligned in the order of icons, search_box, and controls. - EXPECT_LE(GetIconsBounds().right(), GetSearchBoxBounds().x()); - EXPECT_LE(GetSearchBoxBounds().right(), GetControlBounds().x()); - EXPECT_LE(0, GetIconsBounds().y()); - - // Search box should appear in the middle. - EXPECT_NEAR(GetSearchBoxBounds().CenterPoint().x(), - view_->bounds().CenterPoint().x(), - 1); - - // Should fit inside of the home card height. - EXPECT_GE(kHomeCardHeight, GetIconsBounds().height()); - EXPECT_GE(kHomeCardHeight, GetSearchBoxBounds().height()); - EXPECT_GE(kHomeCardHeight, GetControlBounds().height()); - EXPECT_EQ(GetSearchBoxPreferredSize().ToString(), - GetSearchBoxBounds().size().ToString()); - - // CENTERED state. logo is visible. search box appears below the logo, - // icons and controls are arranged horizontally and below the search box. - view_->SetLayoutState(1.0f); - EXPECT_TRUE(IsLogoVisible()); - EXPECT_NEAR(GetLogoBounds().x() + GetLogoBounds().width() / 2, - GetSearchBoxBounds().x() + GetSearchBoxBounds().width() / 2, - 1); - EXPECT_LE(GetLogoBounds().bottom(), GetSearchBoxBounds().y()); - EXPECT_EQ(GetIconsBounds().y(), GetControlBounds().y()); - EXPECT_LE(GetIconsBounds().right(), GetControlBounds().x()); - EXPECT_LE(GetSearchBoxBounds().bottom(), GetIconsBounds().y()); -} - -TEST_F(AthenaStartPageViewTest, NarrowLayout) { - SetSize(gfx::Size(800, 1280)); - - // BOTTOM state. Similar to BasicLayout. - EXPECT_FALSE(IsLogoVisible()); - // Three components are aligned at the middle point. - EXPECT_NEAR(GetIconsBounds().CenterPoint().y(), - GetControlBounds().CenterPoint().y(), - 1); - EXPECT_NEAR(GetIconsBounds().CenterPoint().y(), - GetSearchBoxBounds().CenterPoint().y(), - 1); - EXPECT_NEAR(GetControlBounds().CenterPoint().y(), - GetSearchBoxBounds().CenterPoint().y(), - 1); - - // Horizonttaly aligned in the order of icons, search_box, and controls. - EXPECT_LE(GetIconsBounds().right(), GetSearchBoxBounds().x()); - EXPECT_LE(GetSearchBoxBounds().right(), GetControlBounds().x()); - EXPECT_LE(0, GetIconsBounds().y()); - - // Search box should appear in the middle. - EXPECT_NEAR(GetSearchBoxBounds().CenterPoint().x(), - view_->bounds().CenterPoint().x(), - 1); - - // Should fit inside of the home card height. - EXPECT_GE(kHomeCardHeight, GetIconsBounds().height()); - EXPECT_GE(kHomeCardHeight, GetSearchBoxBounds().height()); - EXPECT_GE(kHomeCardHeight, GetControlBounds().height()); - - // Search box is narrower because of the size is too narrow. - EXPECT_GT(GetSearchBoxPreferredSize().width(), GetSearchBoxBounds().width()); - EXPECT_EQ(GetSearchBoxPreferredSize().height(), - GetSearchBoxBounds().height()); - - // CENTERED state. Search box should be back to the preferred size. - view_->SetLayoutState(1.0f); - EXPECT_EQ(GetSearchBoxPreferredSize().ToString(), - GetSearchBoxBounds().size().ToString()); - - // Back to BOTTOM state, the search box shrinks again. - view_->SetLayoutState(0.0f); - EXPECT_GT(GetSearchBoxPreferredSize().width(), GetSearchBoxBounds().width()); - - // Then set back to the original size, now the size is wide enough so the - // search box bounds becomes as preferred. - SetSize(gfx::Size(1280, 800)); - EXPECT_EQ(GetSearchBoxPreferredSize().ToString(), - GetSearchBoxBounds().size().ToString()); -} - -TEST_F(AthenaStartPageViewTest, SearchBox) { - view_->SetLayoutState(1.0f); - EXPECT_TRUE(IsLogoVisible()); - - const gfx::Rect base_search_box_bounds = GetSearchBoxBounds(); - - const base::string16 query = base::UTF8ToUTF16("test"); - SetSearchQuery(query); - - EXPECT_FALSE(IsLogoVisible()); - EXPECT_GT(base_search_box_bounds.y(), GetSearchBoxBounds().y()); - EXPECT_EQ(query, GetVisibleQuery()); - - SetSearchQuery(base::string16()); - EXPECT_TRUE(IsLogoVisible()); - EXPECT_EQ(base_search_box_bounds.ToString(), GetSearchBoxBounds().ToString()); - EXPECT_TRUE(GetVisibleQuery().empty()); -} - -TEST_F(AthenaStartPageViewTest, SearchFromBottom) { - view_->SetLayoutState(0.0f); - - const base::string16 query = base::UTF8ToUTF16("test"); - SetSearchQuery(query); - - EXPECT_FALSE(IsLogoVisible()); - EXPECT_EQ(query, GetVisibleQuery()); - EXPECT_EQ(1.0f, layout_state()); - - SetSearchQuery(base::string16()); - EXPECT_TRUE(IsLogoVisible()); - EXPECT_TRUE(GetVisibleQuery().empty()); - EXPECT_EQ(1.0f, layout_state()); -} - -TEST_F(AthenaStartPageViewTest, AppAddRemove) { - gfx::Rect icons_bounds = GetIconsBounds(); - EXPECT_EQ(GetMaxIconNum(), - static_cast<size_t>(GetIconsContainer()->child_count())); - - GetModel()->DeleteItem(GetAppIdFor(1)); - - // The removed icon disappear, however its bound should not change. - EXPECT_EQ(GetMaxIconNum() - 1, - static_cast<size_t>(GetIconsContainer()->child_count())); - EXPECT_EQ(icons_bounds.size().ToString(), GetIconsBounds().size().ToString()); - - AddTestItem(GetMaxIconNum() + 1); - EXPECT_EQ(GetMaxIconNum(), - static_cast<size_t>(GetIconsContainer()->child_count())); - EXPECT_EQ(icons_bounds.size().ToString(), GetIconsBounds().size().ToString()); - - // Adding more doesn't cause any effects. - AddTestItem(GetMaxIconNum() + 2); - EXPECT_EQ(GetMaxIconNum(), - static_cast<size_t>(GetIconsContainer()->child_count())); - EXPECT_EQ(icons_bounds.size().ToString(), GetIconsBounds().size().ToString()); -} - -} // namespace athena diff --git a/athena/home/home_card_constants.cc b/athena/home/home_card_constants.cc index 1bf28753bf..2a951c6acf 100644 --- a/athena/home/home_card_constants.cc +++ b/athena/home/home_card_constants.cc @@ -6,7 +6,7 @@ namespace athena { -const int kHomeCardHeight = 100; +const int kHomeCardHeight = 212; const int kHomeCardDragIndicatorHeight = 2; const int kHomeCardDragIndicatorWidth = 48; const int kHomeCardDragIndicatorMarginHeight = 7; diff --git a/athena/home/home_card_gesture_manager_unittest.cc b/athena/home/home_card_gesture_manager_unittest.cc index c5c40fcfee..91d70305fc 100644 --- a/athena/home/home_card_gesture_manager_unittest.cc +++ b/athena/home/home_card_gesture_manager_unittest.cc @@ -186,8 +186,8 @@ TEST_F(HomeCardGestureManagerTest, StartCentered) { EXPECT_EQ(HomeCard::VISIBLE_CENTERED, last_to_state_); EXPECT_EQ(1.0f, last_progress_); - ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 900); - ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 910); + ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 700); + ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 710); EXPECT_EQ(2, GetProgressCountAndReset()); EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, last_from_state_); EXPECT_EQ(HomeCard::VISIBLE_CENTERED, last_to_state_); @@ -218,13 +218,13 @@ TEST_F(HomeCardGestureManagerTest, StartBottom) { EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, final_state_); // State change for the bigger moves. - EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 950)); + EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 850)); ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 1000); EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_END, 1000)); EXPECT_EQ(1, GetEndCountAndReset()); EXPECT_EQ(HomeCard::VISIBLE_MINIMIZED, final_state_); - EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 950)); + EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_BEGIN, 850)); ProcessGestureEvent(ui::ET_GESTURE_SCROLL_UPDATE, 300); EXPECT_TRUE(ProcessGestureEvent(ui::ET_GESTURE_SCROLL_END, 300)); EXPECT_EQ(1, GetEndCountAndReset()); diff --git a/athena/home/home_card_impl.cc b/athena/home/home_card_impl.cc index f6a64f382f..e9f468a4c0 100644 --- a/athena/home/home_card_impl.cc +++ b/athena/home/home_card_impl.cc @@ -9,14 +9,14 @@ #include "athena/env/public/athena_env.h" #include "athena/home/app_list_view_delegate.h" -#include "athena/home/athena_start_page_view.h" #include "athena/home/home_card_constants.h" #include "athena/home/public/app_model_builder.h" #include "athena/screen/public/screen_manager.h" #include "athena/util/container_priorities.h" #include "athena/wm/public/window_manager.h" +#include "ui/app_list/search_box_model.h" #include "ui/app_list/views/app_list_main_view.h" -#include "ui/app_list/views/contents_view.h" +#include "ui/app_list/views/search_box_view.h" #include "ui/aura/layout_manager.h" #include "ui/aura/window.h" #include "ui/compositor/closure_animation_observer.h" @@ -36,6 +36,8 @@ namespace { HomeCard* instance = nullptr; const float kMinimizedHomeOpacity = 0.65f; +const int kIndicatorOffset = 24; +const int kAppListOffset = -128; gfx::Rect GetBoundsForState(const gfx::Rect& screen_bounds, HomeCard::State state) { @@ -122,14 +124,15 @@ class HomeCardLayoutManager : public aura::LayoutManager { }; // The container view of home card contents of each state. -class HomeCardView : public views::WidgetDelegateView, - public AthenaStartPageView::Observer { +class HomeCardView : public views::WidgetDelegateView { public: HomeCardView(app_list::AppListViewDelegate* view_delegate, aura::Window* container, HomeCardGestureManager::Delegate* gesture_delegate) : background_(new views::View), - main_view_(new AthenaStartPageView(view_delegate)), + main_view_(new app_list::AppListMainView(view_delegate)), + search_box_view_( + new app_list::SearchBoxView(main_view_, view_delegate)), minimized_background_(new views::View()), drag_indicator_(new views::View()), gesture_delegate_(gesture_delegate), @@ -141,13 +144,16 @@ class HomeCardView : public views::WidgetDelegateView, background_->SetFillsBoundsOpaquely(false); AddChildView(background_); - // Ideally AppListMainView should be used here and have AthenaStartPageView - // as its child view, so that custom pages and apps grid are available in - // the home card. - // TODO(mukai): make it so after the detailed UI has been fixed. - main_view_->AddObserver(this); + main_view_->SetPaintToLayer(true); + main_view_->SetFillsBoundsOpaquely(false); + main_view_->layer()->SetMasksToBounds(true); AddChildView(main_view_); + search_box_view_->SetPaintToLayer(true); + search_box_view_->SetFillsBoundsOpaquely(false); + search_box_view_->layer()->SetMasksToBounds(true); + AddChildView(search_box_view_); + minimized_background_->set_background( views::Background::CreateSolidBackground( SkColorSetA(SK_ColorBLACK, 256 * kMinimizedHomeOpacity))); @@ -162,17 +168,30 @@ class HomeCardView : public views::WidgetDelegateView, AddChildView(drag_indicator_); } - ~HomeCardView() override { main_view_->RemoveObserver(this); } + void Init() { + main_view_->Init(GetWidget()->GetNativeView(), + -1, /* inital apps page: -1 means default */ + search_box_view_); + } void SetStateProgress(HomeCard::State from_state, HomeCard::State to_state, float progress) { // TODO(mukai): not clear the focus, but simply close the virtual keyboard. GetFocusManager()->ClearFocus(); - if (from_state == HomeCard::VISIBLE_CENTERED) - main_view_->SetLayoutState(1.0f - progress); - else if (to_state == HomeCard::VISIBLE_CENTERED) - main_view_->SetLayoutState(progress); + + gfx::Rect from_main_bounds = GetMainViewBounds(from_state); + gfx::Rect to_main_bounds = GetMainViewBounds(to_state); + if (from_main_bounds != to_main_bounds) { + DCHECK_EQ(from_main_bounds.size().ToString(), + to_main_bounds.size().ToString()); + gfx::Rect main_bounds = gfx::Tween::RectValueBetween( + progress, from_main_bounds, to_main_bounds); + main_view_->SetBoundsRect(main_bounds); + main_bounds.set_height( + search_box_view_->GetHeightForWidth(main_bounds.width())); + search_box_view_->SetBoundsRect(main_bounds); + } float background_opacity = 1.0f; if (from_state == HomeCard::VISIBLE_MINIMIZED || @@ -207,7 +226,8 @@ class HomeCardView : public views::WidgetDelegateView, } void SetStateWithAnimation(HomeCard::State state, - gfx::Tween::Type tween_type) { + gfx::Tween::Type tween_type, + const base::Closure& on_animation_ended) { float minimized_opacity = (state == HomeCard::VISIBLE_MINIMIZED) ? 1.0f : 0.0f; // |minimized_background_| needs to be visible before scheduling animation. @@ -241,20 +261,27 @@ class HomeCardView : public views::WidgetDelegateView, background_->layer()->SetOpacity(background_opacity); } - if (state == HomeCard::VISIBLE_CENTERED) - main_view_->RequestFocusOnSearchBox(); - else - GetWidget()->GetFocusManager()->ClearFocus(); - { ui::ScopedLayerAnimationSettings settings( drag_indicator_->layer()->GetAnimator()); - settings.SetTweenType(gfx::Tween::EASE_IN_OUT); + settings.SetTweenType(tween_type); drag_indicator_->SetBoundsRect(GetDragIndicatorBounds(state)); } - main_view_->SetLayoutStateWithAnimation( - (state == HomeCard::VISIBLE_CENTERED) ? 1.0f : 0.0f, tween_type); + { + ui::ScopedLayerAnimationSettings settings( + main_view_->layer()->GetAnimator()); + settings.SetTweenType(tween_type); + settings.AddObserver( + new ui::ClosureAnimationObserver(on_animation_ended)); + gfx::Rect main_bounds = GetMainViewBounds(state); + main_view_->SetBoundsRect(main_bounds); + main_bounds.set_height( + search_box_view_->GetHeightForWidth(main_bounds.width())); + search_box_view_->SetBoundsRect(main_bounds); + } + + main_view_->UpdateSearchBoxVisibility(); } void ClearGesture() { @@ -282,6 +309,23 @@ class HomeCardView : public views::WidgetDelegateView, return false; } + void Layout() override { + const gfx::Rect contents_bounds = GetContentsBounds(); + background_->SetBoundsRect(contents_bounds); + minimized_background_->SetBoundsRect(contents_bounds); + const gfx::Rect drag_indicator_bounds = + GetDragIndicatorBounds(HomeCard::Get()->GetState()); + drag_indicator_->SetBoundsRect(drag_indicator_bounds); + + gfx::Rect main_bounds(GetMainViewBounds(HomeCard::Get()->GetState())); + main_view_->SetBoundsRect(main_bounds); + + main_bounds.set_height( + search_box_view_->GetHeightForWidth(main_bounds.width())); + search_box_view_->SetBoundsRect(main_bounds); + } + + private: gfx::Rect GetDragIndicatorBounds(HomeCard::State state) { gfx::Rect drag_indicator_bounds( GetContentsBounds().CenterPoint().x() - kHomeCardDragIndicatorWidth / 2, @@ -293,13 +337,19 @@ class HomeCardView : public views::WidgetDelegateView, return drag_indicator_bounds; } - void Layout() override { - gfx::Rect contents_bounds = GetContentsBounds(); - background_->SetBoundsRect(contents_bounds); - main_view_->SetBoundsRect(contents_bounds); - minimized_background_->SetBoundsRect(contents_bounds); - drag_indicator_->SetBoundsRect( - GetDragIndicatorBounds(HomeCard::Get()->GetState())); + gfx::Rect GetMainViewBounds(HomeCard::State state) { + const gfx::Rect contents_bounds = GetContentsBounds(); + const int main_width = main_view_->GetPreferredSize().width(); + gfx::Rect main_bounds( + contents_bounds.CenterPoint().x() - main_width / 2, + GetDragIndicatorBounds(state).bottom() + kIndicatorOffset, + main_width, + contents_bounds.height()); + // This is a bit hacky but slightly shifting up the main_view to fit + // the search box and app icons in the home card. + if (state != HomeCard::VISIBLE_CENTERED) + main_bounds.set_y(kAppListOffset); + return main_bounds; } private: @@ -311,14 +361,9 @@ class HomeCardView : public views::WidgetDelegateView, // views::WidgetDelegate: views::View* GetContentsView() override { return this; } - // AthenaStartPageView::Observer: - void OnLayoutStateChanged(float new_state) override { - if (new_state == 1.0f) - HomeCard::Get()->SetState(HomeCard::VISIBLE_CENTERED); - } - views::View* background_; - AthenaStartPageView* main_view_; + app_list::AppListMainView* main_view_; + app_list::SearchBoxView* search_box_view_; views::View* minimized_background_; views::View* drag_indicator_; HomeCard::State state_; @@ -376,7 +421,12 @@ void HomeCardImpl::Init() { widget_params.delegate = home_card_view_; widget_params.opacity = views::Widget::InitParams::TRANSLUCENT_WINDOW; home_card_widget_->Init(widget_params); + // AppListMainView in home card may move outside of home card layer partially + // in an transition animation. This flag is set to clip the parts outside of + // home card. + home_card_widget_->GetNativeWindow()->layer()->SetMasksToBounds(true); + home_card_view_->Init(); SetState(VISIBLE_MINIMIZED); home_card_view_->Layout(); @@ -388,6 +438,10 @@ aura::Window* HomeCardImpl::GetHomeCardWindowForTest() const { return home_card_widget_ ? home_card_widget_->GetNativeWindow() : nullptr; } +void HomeCardImpl::ResetQuery() { + view_delegate_->GetModel()->search_box()->SetText(base::string16()); +} + void HomeCardImpl::InstallAccelerators() { const AcceleratorData accelerator_data[] = { {TRIGGER_ON_PRESS, ui::VKEY_L, ui::EF_CONTROL_DOWN, @@ -413,7 +467,13 @@ void HomeCardImpl::SetState(HomeCard::State state) { home_card_widget_->ShowInactive(); else home_card_widget_->Show(); - home_card_view_->SetStateWithAnimation(state, gfx::Tween::EASE_IN_OUT); + + // Query should be reset on state change to reset the main_view. Also it's + // not possible to invoke ResetQuery() here, it causes a crash on search. + home_card_view_->SetStateWithAnimation( + state, + gfx::Tween::EASE_IN_OUT, + base::Bind(&HomeCardImpl::ResetQuery, base::Unretained(this))); layout_manager_->Layout(true, gfx::Tween::EASE_IN_OUT); } } @@ -469,7 +529,10 @@ void HomeCardImpl::OnGestureEnded(State final_state, bool is_fling) { // EASE_OUT is better. gfx::Tween::Type tween_type = is_fling ? gfx::Tween::EASE_OUT : gfx::Tween::EASE_IN_OUT; - home_card_view_->SetStateWithAnimation(state_, tween_type); + home_card_view_->SetStateWithAnimation( + state_, + tween_type, + base::Bind(&HomeCardImpl::ResetQuery, base::Unretained(this))); layout_manager_->Layout(true, tween_type); } } diff --git a/athena/home/home_card_impl.h b/athena/home/home_card_impl.h index f330b104e8..a35c31b50d 100644 --- a/athena/home/home_card_impl.h +++ b/athena/home/home_card_impl.h @@ -12,6 +12,10 @@ #include "athena/input/public/accelerator_manager.h" #include "athena/wm/public/window_manager_observer.h" +namespace app_list { +class AppListViewDelegate; +} + namespace aura { class Window; } @@ -30,7 +34,6 @@ class Widget; namespace athena { class AppModelBuilder; -class AppListViewDelegate; class HomeCardLayoutManager; class HomeCardView; @@ -53,6 +56,8 @@ class ATHENA_EXPORT HomeCardImpl : public HomeCard, }; void InstallAccelerators(); + void ResetQuery(); + // Overridden from HomeCard: void SetState(HomeCard::State state) override; State GetState() override; @@ -86,7 +91,7 @@ class ATHENA_EXPORT HomeCardImpl : public HomeCard, views::Widget* home_card_widget_; HomeCardView* home_card_view_; - scoped_ptr<AppListViewDelegate> view_delegate_; + scoped_ptr<app_list::AppListViewDelegate> view_delegate_; HomeCardLayoutManager* layout_manager_; DISALLOW_COPY_AND_ASSIGN(HomeCardImpl); diff --git a/athena/home/home_card_unittest.cc b/athena/home/home_card_unittest.cc index abbdbdfebf..8afa0ae2b1 100644 --- a/athena/home/home_card_unittest.cc +++ b/athena/home/home_card_unittest.cc @@ -28,12 +28,6 @@ aura::Window* GetHomeCardWindow() { GetHomeCardWindowForTest(); } -// Returns true if the keyboard focus is on the search box. -bool IsSearchBoxFocused(aura::Window* home_card) { - return views::Widget::GetWidgetForNativeWindow(home_card)-> - GetContentsView()->GetViewByID(kHomeCardSearchBoxId)->HasFocus(); -} - typedef test::AthenaTestBase HomeCardTest; TEST_F(HomeCardTest, BasicTransition) { @@ -265,35 +259,6 @@ TEST_F(HomeCardTest, GesturesToFullDirectly) { EXPECT_TRUE(WindowManager::Get()->IsOverviewModeActive()); } -TEST_F(HomeCardTest, KeyboardFocus) { - ASSERT_EQ(HomeCard::VISIBLE_MINIMIZED, HomeCard::Get()->GetState()); - aura::Window* home_card = GetHomeCardWindow(); - ASSERT_FALSE(IsSearchBoxFocused(home_card)); - - WindowManager::Get()->EnterOverview(); - ASSERT_FALSE(IsSearchBoxFocused(home_card)); - - ui::test::EventGenerator generator(root_window()); - gfx::Rect screen_rect(root_window()->bounds()); - - const int bottom = screen_rect.bottom(); - const int x = screen_rect.x() + 1; - - generator.GestureScrollSequence(gfx::Point(x, bottom - 40), - gfx::Point(x, 10), - base::TimeDelta::FromSeconds(1), - 10); - EXPECT_EQ(HomeCard::VISIBLE_CENTERED, HomeCard::Get()->GetState()); - EXPECT_TRUE(IsSearchBoxFocused(home_card)); - - generator.GestureScrollSequence(gfx::Point(x, 10), - gfx::Point(x, bottom - 100), - base::TimeDelta::FromSeconds(1), - 10); - EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState()); - EXPECT_FALSE(IsSearchBoxFocused(home_card)); -} - TEST_F(HomeCardTest, DontMinimizeWithModalWindow) { aura::Window* home_card = GetHomeCardWindow(); @@ -313,10 +278,7 @@ TEST_F(HomeCardTest, DontMinimizeWithModalWindow) { modal.reset(); EXPECT_EQ(HomeCard::VISIBLE_BOTTOM, HomeCard::Get()->GetState()); - - // TODO(oshima): The focus should be set to home card. Flip the - // condition once crbug.com/424750 is fixed.a - EXPECT_FALSE(wm::IsActiveWindow(home_card)); + EXPECT_TRUE(wm::IsActiveWindow(home_card)); } } // namespace athena diff --git a/athena/main/DEPS b/athena/main/DEPS index d0ff633099..2724d27414 100644 --- a/athena/main/DEPS +++ b/athena/main/DEPS @@ -31,7 +31,7 @@ include_rules = [ ] specific_include_rules = { - "athena_main\.cc": [ + "athena_main_delegate.*": [ "+content/public/app", "+extensions/browser/app_window", "+extensions/shell/app", diff --git a/athena/main/athena_frame_view.h b/athena/main/athena_frame_view.h index c385ed93ff..b3829a8685 100644 --- a/athena/main/athena_frame_view.h +++ b/athena/main/athena_frame_view.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ATHENA_COMMON_ATHENA_FRAME_VIEW_H_ -#define ATHENA_COMMON_ATHENA_FRAME_VIEW_H_ +#ifndef ATHENA_MAIN_ATHENA_FRAME_VIEW_H_ +#define ATHENA_MAIN_ATHENA_FRAME_VIEW_H_ #include "ui/views/window/non_client_view.h" @@ -54,4 +54,4 @@ class AthenaFrameView : public views::NonClientFrameView { } // namespace athena -#endif // ATHENA_COMMON_ATHENA_FRAME_VIEW_H_ +#endif // ATHENA_MAIN_ATHENA_FRAME_VIEW_H_ diff --git a/athena/main/athena_main.cc b/athena/main/athena_main.cc index 98fe171c84..1eab12834d 100644 --- a/athena/main/athena_main.cc +++ b/athena/main/athena_main.cc @@ -2,196 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "athena/activity/public/activity_factory.h" -#include "athena/activity/public/activity_manager.h" -#include "athena/content/public/web_contents_view_delegate_creator.h" -#include "athena/env/public/athena_env.h" -#include "athena/extensions/public/extensions_delegate.h" -#include "athena/main/athena_content_client.h" -#include "athena/main/athena_renderer_pdf_helper.h" -#include "athena/main/public/athena_launcher.h" -#include "athena/screen/public/screen_manager.h" -#include "base/command_line.h" -#include "base/files/file_util.h" -#include "base/path_service.h" -#include "components/pdf/renderer/ppb_pdf_impl.h" +#include "athena/main/athena_main_delegate.h" #include "content/public/app/content_main.h" -#include "content/public/browser/browser_thread.h" -#include "extensions/browser/app_window/app_window.h" -#include "extensions/browser/app_window/app_window_client.h" -#include "extensions/shell/app/shell_main_delegate.h" -#include "extensions/shell/browser/desktop_controller.h" -#include "extensions/shell/browser/shell_app_delegate.h" -#include "extensions/shell/browser/shell_browser_main_delegate.h" -#include "extensions/shell/browser/shell_content_browser_client.h" -#include "extensions/shell/browser/shell_extension_system.h" -#include "extensions/shell/browser/shell_native_app_window.h" -#include "extensions/shell/common/shell_content_client.h" -#include "extensions/shell/common/switches.h" -#include "extensions/shell/renderer/shell_content_renderer_client.h" -#include "ppapi/c/private/ppb_pdf.h" -#include "ui/aura/window_tree_host.h" -#include "ui/base/resource/resource_bundle.h" -#include "ui/wm/core/visibility_controller.h" - -namespace { - -// We want to load the sample calculator app by default, for a while. Expecting -// to run athena_main at src/ -const char kDefaultAppPath[] = - "chrome/common/extensions/docs/examples/apps/calculator/app"; - -} // namespace - -class AthenaDesktopController : public extensions::DesktopController { - public: - AthenaDesktopController() {} - ~AthenaDesktopController() override {} - - private: - // extensions::DesktopController: - virtual aura::WindowTreeHost* GetHost() override { - return athena::AthenaEnv::Get()->GetHost(); - } - - // Creates a new app window and adds it to the desktop. The desktop maintains - // ownership of the window. - // TODO(jamescook|oshima): Is this function needed? - virtual extensions::AppWindow* CreateAppWindow( - content::BrowserContext* context, - const extensions::Extension* extension) override { - NOTIMPLEMENTED(); - return nullptr; - } - - // Adds the window to the desktop. - virtual void AddAppWindow(aura::Window* window) override { - NOTIMPLEMENTED(); - } - - virtual void RemoveAppWindow(extensions::AppWindow* window) override {} - - // Closes and destroys the app windows. - virtual void CloseAppWindows() override {} - - DISALLOW_COPY_AND_ASSIGN(AthenaDesktopController); -}; - -class AthenaBrowserMainDelegate : public extensions::ShellBrowserMainDelegate { - public: - AthenaBrowserMainDelegate() {} - ~AthenaBrowserMainDelegate() override {} - - // extensions::ShellBrowserMainDelegate: - virtual void Start(content::BrowserContext* context) override { - base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); - - base::FilePath app_dir = base::FilePath::FromUTF8Unsafe( - command_line->HasSwitch(extensions::switches::kAppShellAppPath) - ? command_line->GetSwitchValueNative( - extensions::switches::kAppShellAppPath) - : kDefaultAppPath); - - base::FilePath app_absolute_dir = base::MakeAbsoluteFilePath(app_dir); - if (base::DirectoryExists(app_absolute_dir)) { - extensions::ShellExtensionSystem* extension_system = - static_cast<extensions::ShellExtensionSystem*>( - extensions::ExtensionSystem::Get(context)); - extension_system->LoadApp(app_absolute_dir); - } - - athena::StartAthenaEnv(content::BrowserThread::GetBlockingPool()-> - GetTaskRunnerWithShutdownBehavior( - base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); - athena::CreateVirtualKeyboardWithContext(context); - athena::StartAthenaSessionWithContext(context); - } - - virtual void Shutdown() override { - athena::AthenaEnv::Get()->OnTerminating(); - athena::ShutdownAthena(); - } - - virtual extensions::DesktopController* CreateDesktopController() override { - return new AthenaDesktopController(); - } - - private: - DISALLOW_COPY_AND_ASSIGN(AthenaBrowserMainDelegate); -}; - -class AthenaContentBrowserClient - : public extensions::ShellContentBrowserClient { - public: - AthenaContentBrowserClient() - : extensions::ShellContentBrowserClient(new AthenaBrowserMainDelegate()) { - } - ~AthenaContentBrowserClient() override {} - - // content::ContentBrowserClient: - virtual content::WebContentsViewDelegate* GetWebContentsViewDelegate( - content::WebContents* web_contents) override { - return athena::CreateWebContentsViewDelegate(web_contents); - } - - private: - DISALLOW_COPY_AND_ASSIGN(AthenaContentBrowserClient); -}; - -class AthenaContentRendererClient - : public extensions::ShellContentRendererClient { - public: - AthenaContentRendererClient() {} - ~AthenaContentRendererClient() override {} - - // content::ContentRendererClient: - virtual void RenderFrameCreated(content::RenderFrame* render_frame) override { - new athena::AthenaRendererPDFHelper(render_frame); - extensions::ShellContentRendererClient::RenderFrameCreated(render_frame); - } - - virtual const void* CreatePPAPIInterface( - const std::string& interface_name) override { - if (interface_name == PPB_PDF_INTERFACE) - return pdf::PPB_PDF_Impl::GetInterface(); - return extensions::ShellContentRendererClient::CreatePPAPIInterface( - interface_name); - } -}; - -class AthenaMainDelegate : public extensions::ShellMainDelegate { - public: - AthenaMainDelegate() {} - ~AthenaMainDelegate() override {} - - private: - // extensions::ShellMainDelegate: - virtual content::ContentClient* CreateContentClient() override { - return new athena::AthenaContentClient(); - } - virtual content::ContentBrowserClient* CreateShellContentBrowserClient() - override { - return new AthenaContentBrowserClient(); - } - - virtual content::ContentRendererClient* CreateShellContentRendererClient() - override { - return new AthenaContentRendererClient(); - } - - virtual void InitializeResourceBundle() override { - base::FilePath pak_dir; - PathService::Get(base::DIR_MODULE, &pak_dir); - base::FilePath pak_file = - pak_dir.Append(FILE_PATH_LITERAL("athena_resources.pak")); - ui::ResourceBundle::InitSharedInstanceWithPakPath(pak_file); - } - - DISALLOW_COPY_AND_ASSIGN(AthenaMainDelegate); -}; int main(int argc, const char** argv) { - AthenaMainDelegate delegate; + athena::AthenaMainDelegate delegate; content::ContentMainParams params(&delegate); params.argc = argc; diff --git a/athena/main/athena_main.gyp b/athena/main/athena_main.gyp index c829ad6db4..a14df3701f 100644 --- a/athena/main/athena_main.gyp +++ b/athena/main/athena_main.gyp @@ -39,6 +39,8 @@ 'athena_frame_view.cc', 'athena_frame_view.h', 'athena_launcher.cc', + 'athena_main_delegate.cc', + 'athena_main_delegate.h', 'athena_renderer_pdf_helper.cc', 'athena_renderer_pdf_helper.h', 'athena_views_delegate.cc', diff --git a/athena/main/athena_main_delegate.cc b/athena/main/athena_main_delegate.cc new file mode 100644 index 0000000000..59c6c42dbd --- /dev/null +++ b/athena/main/athena_main_delegate.cc @@ -0,0 +1,175 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "athena/main/athena_main_delegate.h" + +#include "athena/content/public/web_contents_view_delegate_creator.h" +#include "athena/env/public/athena_env.h" +#include "athena/main/athena_content_client.h" +#include "athena/main/athena_renderer_pdf_helper.h" +#include "athena/main/public/athena_launcher.h" +#include "base/command_line.h" +#include "base/files/file_util.h" +#include "base/path_service.h" +#include "components/pdf/renderer/ppb_pdf_impl.h" +#include "content/public/app/content_main.h" +#include "content/public/browser/browser_thread.h" +#include "extensions/shell/browser/desktop_controller.h" +#include "extensions/shell/browser/shell_browser_main_delegate.h" +#include "extensions/shell/browser/shell_content_browser_client.h" +#include "extensions/shell/browser/shell_extension_system.h" +#include "extensions/shell/common/shell_content_client.h" +#include "extensions/shell/common/switches.h" +#include "extensions/shell/renderer/shell_content_renderer_client.h" +#include "ppapi/c/private/ppb_pdf.h" +#include "ui/base/resource/resource_bundle.h" + +namespace athena { +namespace { + +// We want to load the sample calculator app by default, for a while. Expecting +// to run athena_main at src/ +const char kDefaultAppPath[] = + "chrome/common/extensions/docs/examples/apps/calculator/app"; + +class AthenaDesktopController : public extensions::DesktopController { + public: + AthenaDesktopController() {} + ~AthenaDesktopController() override {} + + private: + // extensions::DesktopController: + virtual aura::WindowTreeHost* GetHost() override { + return athena::AthenaEnv::Get()->GetHost(); + } + + // Creates a new app window and adds it to the desktop. The desktop maintains + // ownership of the window. + // TODO(jamescook|oshima): Is this function needed? + virtual extensions::AppWindow* CreateAppWindow( + content::BrowserContext* context, + const extensions::Extension* extension) override { + NOTIMPLEMENTED(); + return nullptr; + } + + // Adds the window to the desktop. + virtual void AddAppWindow(aura::Window* window) override { NOTIMPLEMENTED(); } + + virtual void RemoveAppWindow(extensions::AppWindow* window) override {} + + // Closes and destroys the app windows. + virtual void CloseAppWindows() override {} + + DISALLOW_COPY_AND_ASSIGN(AthenaDesktopController); +}; + +class AthenaBrowserMainDelegate : public extensions::ShellBrowserMainDelegate { + public: + AthenaBrowserMainDelegate() {} + ~AthenaBrowserMainDelegate() override {} + + // extensions::ShellBrowserMainDelegate: + virtual void Start(content::BrowserContext* context) override { + base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); + + base::FilePath app_dir = base::FilePath::FromUTF8Unsafe( + command_line->HasSwitch(extensions::switches::kAppShellAppPath) + ? command_line->GetSwitchValueNative( + extensions::switches::kAppShellAppPath) + : kDefaultAppPath); + + base::FilePath app_absolute_dir = base::MakeAbsoluteFilePath(app_dir); + if (base::DirectoryExists(app_absolute_dir)) { + extensions::ShellExtensionSystem* extension_system = + static_cast<extensions::ShellExtensionSystem*>( + extensions::ExtensionSystem::Get(context)); + extension_system->LoadApp(app_absolute_dir); + } + + athena::StartAthenaEnv( + content::BrowserThread::GetBlockingPool() + ->GetTaskRunnerWithShutdownBehavior( + base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); + athena::CreateVirtualKeyboardWithContext(context); + athena::StartAthenaSessionWithContext(context); + } + + virtual void Shutdown() override { + athena::AthenaEnv::Get()->OnTerminating(); + athena::ShutdownAthena(); + } + + virtual extensions::DesktopController* CreateDesktopController() override { + return new AthenaDesktopController(); + } + + private: + DISALLOW_COPY_AND_ASSIGN(AthenaBrowserMainDelegate); +}; + +class AthenaContentBrowserClient + : public extensions::ShellContentBrowserClient { + public: + AthenaContentBrowserClient() + : extensions::ShellContentBrowserClient(new AthenaBrowserMainDelegate()) { + } + ~AthenaContentBrowserClient() override {} + + // content::ContentBrowserClient: + virtual content::WebContentsViewDelegate* GetWebContentsViewDelegate( + content::WebContents* web_contents) override { + return athena::CreateWebContentsViewDelegate(web_contents); + } + + private: + DISALLOW_COPY_AND_ASSIGN(AthenaContentBrowserClient); +}; + +class AthenaContentRendererClient + : public extensions::ShellContentRendererClient { + public: + AthenaContentRendererClient() {} + ~AthenaContentRendererClient() override {} + + // content::ContentRendererClient: + virtual void RenderFrameCreated(content::RenderFrame* render_frame) override { + new athena::AthenaRendererPDFHelper(render_frame); + extensions::ShellContentRendererClient::RenderFrameCreated(render_frame); + } + + virtual const void* CreatePPAPIInterface( + const std::string& interface_name) override { + if (interface_name == PPB_PDF_INTERFACE) + return pdf::PPB_PDF_Impl::GetInterface(); + return extensions::ShellContentRendererClient::CreatePPAPIInterface( + interface_name); + } +}; + +} // namespace + +content::ContentClient* AthenaMainDelegate::CreateContentClient() { + return new athena::AthenaContentClient(); +} + +content::ContentBrowserClient* +AthenaMainDelegate::CreateShellContentBrowserClient() { + return new AthenaContentBrowserClient(); +} + +content::ContentRendererClient* +AthenaMainDelegate::CreateShellContentRendererClient() { + return new AthenaContentRendererClient(); +} + +void AthenaMainDelegate::InitializeResourceBundle() { + base::FilePath pak_dir; + PathService::Get(base::DIR_MODULE, &pak_dir); + base::FilePath pak_file = + pak_dir.Append(FILE_PATH_LITERAL("athena_resources.pak")); + ui::ResourceBundle::InitSharedInstanceWithPakPath(pak_file); +} + +} // namespace athena diff --git a/athena/main/athena_main_delegate.h b/athena/main/athena_main_delegate.h new file mode 100644 index 0000000000..14ce0812e4 --- /dev/null +++ b/athena/main/athena_main_delegate.h @@ -0,0 +1,29 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ATHENA_MAIN_ATHENA_MAIN_DELEGATE_H_ +#define ATHENA_MAIN_ATHENA_MAIN_DELEGATE_H_ + +#include "extensions/shell/app/shell_main_delegate.h" + +namespace athena { + +class AthenaMainDelegate : public extensions::ShellMainDelegate { + public: + AthenaMainDelegate() {} + ~AthenaMainDelegate() override {} + + private: + // extensions::ShellMainDelegate: + content::ContentClient* CreateContentClient() override; + content::ContentBrowserClient* CreateShellContentBrowserClient() override; + content::ContentRendererClient* CreateShellContentRendererClient() override; + void InitializeResourceBundle() override; + + DISALLOW_COPY_AND_ASSIGN(AthenaMainDelegate); +}; + +} // namespace + +#endif // ATHENA_MAIN_ATHENA_MAIN_DELEGATE_H_ diff --git a/athena/screen/modal_window_controller.cc b/athena/screen/modal_window_controller.cc index 90357e9ce4..140b2c9aba 100644 --- a/athena/screen/modal_window_controller.cc +++ b/athena/screen/modal_window_controller.cc @@ -111,6 +111,12 @@ void ModalWindowController::UpdateDimming(aura::Window* ignore) { // invisible, but don't delete it until next event execution // because the call stack may still have and use the pointer. modal_container_->RemoveObserver(this); + + // Hide the window before removing it, so the focus manager which will run + // in RemoveChild handler can know that this container is no longer + // available. + modal_container_->Hide(); + modal_container_->parent()->RemoveChild(modal_container_); base::MessageLoopForUI::current()->DeleteSoon(FROM_HERE, modal_container_); modal_container_ = nullptr; diff --git a/athena/screen/screen_manager_impl.cc b/athena/screen/screen_manager_impl.cc index 471df3b29d..20a4bd5d33 100644 --- a/athena/screen/screen_manager_impl.cc +++ b/athena/screen/screen_manager_impl.cc @@ -51,7 +51,7 @@ struct HigherPriorityFinder { bool BlockEvents(aura::Window* container) { ScreenManager::ContainerParams* params = container->GetProperty(kContainerParamsKey); - return params && params->block_events; + return params && params->block_events && container->IsVisible(); } bool DefaultContainer(aura::Window* container) { @@ -109,11 +109,47 @@ class AthenaFocusRules : public wm::BaseFocusRules { return BaseFocusRules::CanActivateWindow(window); } + aura::Window* GetTopmostWindowToActivateInContainer( + aura::Window* container, + aura::Window* ignore) const { + for (aura::Window::Windows::const_reverse_iterator i = + container->children().rbegin(); + i != container->children().rend(); + ++i) { + if (*i != ignore && CanActivateWindow(*i)) + return *i; + } + return NULL; + } + virtual aura::Window* GetNextActivatableWindow( aura::Window* ignore) const override { - aura::Window* next = wm::BaseFocusRules::GetNextActivatableWindow(ignore); - // TODO(oshima): Search from activatable containers if |next| is nullptr. - // crbug.com/424750. + const aura::Window::Windows& containers = + ignore->GetRootWindow()->children(); + auto starting_container_iter = containers.begin(); + for (auto container_iter = containers.begin(); + container_iter != containers.end(); + container_iter++) { + if ((*container_iter)->Contains(ignore)) { + starting_container_iter = container_iter; + break; + } + } + + // Find next window from the front containers. + aura::Window* next = nullptr; + for (auto container_iter = starting_container_iter; + !next && container_iter != containers.end(); + container_iter++) { + next = GetTopmostWindowToActivateInContainer(*container_iter, ignore); + } + + // Find next window from the back containers. + auto container_iter = starting_container_iter; + while (!next && container_iter != containers.begin()) { + container_iter--; + next = GetTopmostWindowToActivateInContainer(*container_iter, ignore); + } return next; } diff --git a/athena/screen/screen_manager_unittest.cc b/athena/screen/screen_manager_unittest.cc index dd634ba44a..15588d34e4 100644 --- a/athena/screen/screen_manager_unittest.cc +++ b/athena/screen/screen_manager_unittest.cc @@ -15,7 +15,8 @@ #include "ui/events/test/event_generator.h" #include "ui/wm/core/window_util.h" -typedef athena::test::AthenaTestBase ScreenManagerTest; +using ScreenManagerTest = athena::test::AthenaTestBase; +using AthenaFocusRuleTest = athena::test::AthenaTestBase; namespace athena { namespace { @@ -163,6 +164,91 @@ TEST_F(ScreenManagerTest, DefaultContainer) { parent->AddChild(original_default); } +TEST_F(AthenaFocusRuleTest, FocusTravarsalFromSameContainer) { + ScreenManager::ContainerParams params("contaier", kTestZOrderPriority); + params.can_activate_children = true; + scoped_ptr<aura::Window> + container(ScreenManager::Get()->CreateContainer(params)); + + scoped_ptr<aura::Window> w1(CreateWindow( + container.get(), nullptr, gfx::Rect(0, 0, 100, 100))); + wm::ActivateWindow(w1.get()); + EXPECT_TRUE(wm::IsActiveWindow(w1.get())); + + scoped_ptr<aura::Window> w2(CreateWindow( + container.get(), nullptr, gfx::Rect(0, 0, 100, 100))); + EXPECT_TRUE(wm::IsActiveWindow(w1.get())); + + container->RemoveChild(w1.get()); + EXPECT_TRUE(wm::IsActiveWindow(w2.get())); +} + +TEST_F(AthenaFocusRuleTest, FocusTravarsalFromOtherContainer) { + ScreenManager::ContainerParams params2("contaier2", kTestZOrderPriority + 1); + params2.can_activate_children = true; + scoped_ptr<aura::Window> + container2(ScreenManager::Get()->CreateContainer(params2)); + scoped_ptr<aura::Window> w2(CreateWindow( + container2.get(), nullptr, gfx::Rect(0, 0, 100, 100))); + wm::ActivateWindow(w2.get()); + EXPECT_TRUE(wm::IsActiveWindow(w2.get())); + + ScreenManager::ContainerParams params1("contaier1", kTestZOrderPriority); + params1.can_activate_children = true; + scoped_ptr<aura::Window> + container1(ScreenManager::Get()->CreateContainer(params1)); + ScreenManager::ContainerParams params3("contaier3", kTestZOrderPriority + 2); + params3.can_activate_children = true; + scoped_ptr<aura::Window> + container3(ScreenManager::Get()->CreateContainer(params3)); + scoped_ptr<aura::Window> w1(CreateWindow( + container1.get(), nullptr, gfx::Rect(0, 0, 100, 100))); + scoped_ptr<aura::Window> w3(CreateWindow( + container3.get(), nullptr, gfx::Rect(0, 0, 100, 100))); + + EXPECT_TRUE(wm::IsActiveWindow(w2.get())); + + container2->RemoveChild(w2.get()); + // Focus moves to a window in the front contaier. + EXPECT_TRUE(wm::IsActiveWindow(w3.get())); + + container3->RemoveChild(w3.get()); + // Focus moves to a window in the back contaier. + EXPECT_TRUE(wm::IsActiveWindow(w1.get())); +} + +TEST_F(AthenaFocusRuleTest, FocusTravarsalFromEventBlockedContainer) { + ScreenManager::ContainerParams params1("contaier1", kTestZOrderPriority + 1); + params1.can_activate_children = true; + scoped_ptr<aura::Window> + container1(ScreenManager::Get()->CreateContainer(params1)); + + ScreenManager::ContainerParams params2("contaier2", kTestZOrderPriority + 2); + params2.can_activate_children = true; + params2.block_events = true; + scoped_ptr<aura::Window> + container2(ScreenManager::Get()->CreateContainer(params2)); + + scoped_ptr<aura::Window> w1(CreateWindow( + container1.get(), nullptr, gfx::Rect(0, 0, 100, 100))); + scoped_ptr<aura::Window> w2(CreateWindow( + container2.get(), nullptr, gfx::Rect(0, 0, 100, 100))); + + wm::ActivateWindow(w2.get()); + EXPECT_TRUE(wm::IsActiveWindow(w2.get())); + + // Confirm that w1 can't get the focus. + wm::ActivateWindow(w1.get()); + EXPECT_FALSE(wm::IsActiveWindow(w1.get())); + EXPECT_TRUE(wm::IsActiveWindow(w2.get())); + + container2->Hide(); + w2.reset(); + container2.reset(); + + EXPECT_TRUE(wm::IsActiveWindow(w1.get())); +} + namespace { class ScreenManagerTargeterTest diff --git a/athena/test/base/DEPS b/athena/test/base/DEPS new file mode 100644 index 0000000000..abfd99b469 --- /dev/null +++ b/athena/test/base/DEPS @@ -0,0 +1,6 @@ +include_rules = [ + "+athena/main", + "+content/public", + "+extensions/browser", + "+extensions/shell", +] diff --git a/athena/test/base/athena_browser_test.cc b/athena/test/base/athena_browser_test.cc new file mode 100644 index 0000000000..1348647e1a --- /dev/null +++ b/athena/test/base/athena_browser_test.cc @@ -0,0 +1,61 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "athena/test/base/athena_browser_test.h" + +#include "athena/activity/public/activity_manager.h" +#include "athena/content/public/web_contents_view_delegate_creator.h" +#include "athena/env/public/athena_env.h" +#include "athena/main/athena_content_client.h" +#include "athena/main/athena_renderer_pdf_helper.h" +#include "athena/main/public/athena_launcher.h" +#include "athena/test/base/test_util.h" +#include "base/command_line.h" +#include "base/logging.h" +#include "content/public/browser/browser_thread.h" +#include "content/public/common/content_switches.h" +#include "extensions/shell/browser/shell_content_browser_client.h" + +namespace athena { +namespace test { + +AthenaBrowserTest::AthenaBrowserTest() { +} + +AthenaBrowserTest::~AthenaBrowserTest() { +} + +content::BrowserContext* AthenaBrowserTest::GetBrowserContext() { + return extensions::ShellContentBrowserClient::Get()->GetBrowserContext(); +} + +void AthenaBrowserTest::SetUpCommandLine(base::CommandLine* command_line) { + command_line->AppendSwitchASCII(switches::kTestType, "athena"); + // The NaCl sandbox won't work in our browser tests. + command_line->AppendSwitch(switches::kNoSandbox); + content::BrowserTestBase::SetUpCommandLine(command_line); +} + +void AthenaBrowserTest::SetUpOnMainThread() { + content::BrowserContext* context = GetBrowserContext(); + athena::StartAthenaEnv(content::BrowserThread::GetBlockingPool() + ->GetTaskRunnerWithShutdownBehavior( + base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); + athena::CreateVirtualKeyboardWithContext(context); + athena::StartAthenaSessionWithContext(context); + + // Set the memory pressure to low and turning off undeterministic resource + // observer events. + test_util::SendTestMemoryPressureEvent(ResourceManager::MEMORY_PRESSURE_LOW); +} + +void AthenaBrowserTest::RunTestOnMainThreadLoop() { + base::MessageLoopForUI::current()->RunUntilIdle(); + SetUpOnMainThread(); + RunTestOnMainThread(); + TearDownOnMainThread(); +} + +} // namespace test +} // namespace athena diff --git a/athena/test/base/athena_browser_test.h b/athena/test/base/athena_browser_test.h new file mode 100644 index 0000000000..4ed6d21b76 --- /dev/null +++ b/athena/test/base/athena_browser_test.h @@ -0,0 +1,45 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ATHENA_TEST_BASE_ATHENA_BROWSER_TEST_H_ +#define ATHENA_TEST_BASE_ATHENA_BROWSER_TEST_H_ + +#include "base/memory/scoped_ptr.h" +#include "content/public/test/browser_test.h" +#include "content/public/test/browser_test_base.h" + +namespace base { +class CommandLine; +} + +namespace content { +class BrowserContext; +} + +namespace athena { +namespace test { + +// Base class for athena browser tests. +class AthenaBrowserTest : public content::BrowserTestBase { + public: + AthenaBrowserTest(); + ~AthenaBrowserTest() override; + + protected: + // Returns the browser context used by the test. + content::BrowserContext* GetBrowserContext(); + + private: + // content::BrowserTestBase implementation. + void SetUpCommandLine(base::CommandLine* command_line) override; + void SetUpOnMainThread() override; + void RunTestOnMainThreadLoop() override; + + DISALLOW_COPY_AND_ASSIGN(AthenaBrowserTest); +}; + +} // namespace test +} // namespace athena + +#endif // ATHENA_TEST_BASE_ATHENA_BROWSER_TEST_H_ diff --git a/athena/test/base/athena_browser_test_main.cc b/athena/test/base/athena_browser_test_main.cc new file mode 100644 index 0000000000..a6258fe9f3 --- /dev/null +++ b/athena/test/base/athena_browser_test_main.cc @@ -0,0 +1,15 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <algorithm> + +#include "athena/test/base/athena_test_launcher_delegate.h" +#include "base/sys_info.h" +#include "testing/gtest/include/gtest/gtest.h" + +int main(int argc, char** argv) { + int default_jobs = std::max(1, base::SysInfo::NumberOfProcessors() / 2); + athena::test::AthenaTestLauncherDelegate launcher_delegate; + return content::LaunchTests(&launcher_delegate, default_jobs, argc, argv); +} diff --git a/athena/test/base/athena_test_launcher_delegate.cc b/athena/test/base/athena_test_launcher_delegate.cc new file mode 100644 index 0000000000..0e800c9509 --- /dev/null +++ b/athena/test/base/athena_test_launcher_delegate.cc @@ -0,0 +1,29 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "athena/test/base/athena_test_launcher_delegate.h" + +#include "athena/main/athena_main_delegate.h" +#include "base/test/test_suite.h" + +namespace athena { +namespace test { + +int AthenaTestLauncherDelegate::RunTestSuite(int argc, char** argv) { + return base::TestSuite(argc, argv).Run(); +} + +bool AthenaTestLauncherDelegate::AdjustChildProcessCommandLine( + base::CommandLine* command_line, + const base::FilePath& temp_data_dir) { + return true; +} + +content::ContentMainDelegate* +AthenaTestLauncherDelegate::CreateContentMainDelegate() { + return new AthenaMainDelegate(); +} + +} // namespace test +} // namespace extensions diff --git a/athena/test/base/athena_test_launcher_delegate.h b/athena/test/base/athena_test_launcher_delegate.h new file mode 100644 index 0000000000..c3d621fefa --- /dev/null +++ b/athena/test/base/athena_test_launcher_delegate.h @@ -0,0 +1,25 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef ATHENA_TEST_BASE_ATHENA_TEST_LAUNCHER_DELEGATE_H_ +#define ATHENA_TEST_BASE_ATHENA_TEST_LAUNCHER_DELEGATE_H_ + +#include "content/public/test/test_launcher.h" + +namespace athena { +namespace test { + +class AthenaTestLauncherDelegate : public content::TestLauncherDelegate { + public: + int RunTestSuite(int argc, char** argv) override; + bool AdjustChildProcessCommandLine( + base::CommandLine* command_line, + const base::FilePath& temp_data_dir) override; + content::ContentMainDelegate* CreateContentMainDelegate() override; +}; + +} // namespace test +} // namespace athena + +#endif // ATHENA_TEST_BASE_ATHENA_TEST_LAUNCHER_DELEGATE_H_ diff --git a/athena/test/chrome/test_util.cc b/athena/test/base/test_util.cc index c7af61989d..7e88e1070d 100644 --- a/athena/test/chrome/test_util.cc +++ b/athena/test/base/test_util.cc @@ -2,12 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "athena/test/chrome/test_util.h" +#include "athena/test/base/test_util.h" #include "athena/activity/public/activity.h" #include "athena/activity/public/activity_factory.h" #include "athena/resource_manager/public/resource_manager.h" -#include "chrome/browser/profiles/profile_manager.h" #include "content/public/browser/notification_service.h" #include "content/public/test/test_utils.h" #include "extensions/browser/notification_types.h" @@ -38,9 +37,5 @@ void WaitUntilIdle() { base::MessageLoopForUI::current()->RunUntilIdle(); } -content::BrowserContext* GetBrowserContext() { - return ProfileManager::GetActiveUserProfile(); -} - } // namespace test_util } // namespace athena diff --git a/athena/test/chrome/test_util.h b/athena/test/base/test_util.h index 067548a315..1b2430f7a9 100644 --- a/athena/test/chrome/test_util.h +++ b/athena/test/base/test_util.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ATHENA_TEST_CHROME_TEST_UTIL_H_ -#define ATHENA_TEST_CHROME_TEST_UTIL_H_ +#ifndef ATHENA_TEST_BASE_TEST_UTIL_H_ +#define ATHENA_TEST_BASE_TEST_UTIL_H_ #include "athena/resource_manager/public/resource_manager.h" #include "base/strings/string16.h" @@ -30,12 +30,8 @@ Activity* CreateTestWebActivity(content::BrowserContext* context, // Wait until the system is idle. void WaitUntilIdle(); -// Returns a |BrowserContext| which can be used by tests. -content::BrowserContext* GetBrowserContext(); - } // namespace test_util } // namespace athena -#endif // ATHENA_TEST_CHROME_TEST_UTIL_H_ - +#endif // ATHENA_TEST_BASE_TEST_UTIL_H_ diff --git a/athena/test/chrome/DEPS b/athena/test/chrome/DEPS index 3fd16abaa0..76f3b440b4 100644 --- a/athena/test/chrome/DEPS +++ b/athena/test/chrome/DEPS @@ -3,6 +3,4 @@ include_rules = [ "+chrome/browser/profiles", "+chrome/test/base", "+content/public", - "+extensions/browser", ] - diff --git a/athena/test/chrome/athena_app_browsertest.cc b/athena/test/chrome/athena_app_browser_test.cc index 5b2ddeb85d..4ade37aa12 100644 --- a/athena/test/chrome/athena_app_browsertest.cc +++ b/athena/test/chrome/athena_app_browser_test.cc @@ -2,11 +2,12 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "athena/test/chrome/athena_app_browsertest.h" +#include "athena/test/chrome/athena_app_browser_test.h" #include "athena/extensions/public/extensions_delegate.h" #include "athena/test/base/activity_lifetime_tracker.h" -#include "athena/test/chrome/test_util.h" +#include "athena/test/base/test_util.h" +#include "chrome/browser/profiles/profile_manager.h" #include "content/public/browser/notification_service.h" #include "content/public/common/content_switches.h" #include "content/public/test/test_utils.h" @@ -34,7 +35,7 @@ Activity* AthenaAppBrowserTest::CreateTestAppActivity( content::NOTIFICATION_LOAD_COMPLETED_MAIN_FRAME, content::NotificationService::AllSources()); - ExtensionsDelegate::Get(test_util::GetBrowserContext())->LaunchApp(app_id); + ExtensionsDelegate::Get(GetBrowserContext())->LaunchApp(app_id); observer.Wait(); return tracker.GetNewActivityAndReset(); @@ -58,4 +59,8 @@ void AthenaAppBrowserTest::SetUpOnMainThread() { test_util::SendTestMemoryPressureEvent(ResourceManager::MEMORY_PRESSURE_LOW); } +content::BrowserContext* AthenaAppBrowserTest::GetBrowserContext() { + return ProfileManager::GetActiveUserProfile(); +} + } // namespace athena diff --git a/athena/test/chrome/athena_app_browsertest.h b/athena/test/chrome/athena_app_browser_test.h index 8aa9f2771b..87ae3c9b11 100644 --- a/athena/test/chrome/athena_app_browsertest.h +++ b/athena/test/chrome/athena_app_browser_test.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ATHENA_TEST_CHROME_ATHENA_APP_BROWSERTEST_H_ -#define ATHENA_TEST_CHROME_ATHENA_APP_BROWSERTEST_H_ +#ifndef ATHENA_TEST_CHROME_ATHENA_APP_BROWSER_TEST_H_ +#define ATHENA_TEST_CHROME_ATHENA_APP_BROWSER_TEST_H_ #include "chrome/browser/apps/app_browsertest_util.h" @@ -32,6 +32,9 @@ class AthenaAppBrowserTest : public extensions::PlatformAppBrowserTest { // BrowserTestBase: void SetUpOnMainThread() override; + // Returns the browser context used by the test. + content::BrowserContext* GetBrowserContext(); + private: // Our created app id - after it got created and installed. std::string app_id_; @@ -41,5 +44,4 @@ class AthenaAppBrowserTest : public extensions::PlatformAppBrowserTest { } // namespace athena -#endif // ATHENA_TEST_CHROME_ATHENA_APP_BROWSERTEST_H_ - +#endif // ATHENA_TEST_CHROME_ATHENA_APP_BROWSER_TEST_H_ diff --git a/athena/test/chrome/athena_browsertest.cc b/athena/test/chrome/athena_chrome_browser_test.cc index c9e8965e7a..c619b0aad9 100644 --- a/athena/test/chrome/athena_browsertest.cc +++ b/athena/test/chrome/athena_chrome_browser_test.cc @@ -2,30 +2,36 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "athena/test/chrome/athena_browsertest.h" +#include "athena/test/chrome/athena_chrome_browser_test.h" -#include "athena/test/chrome/test_util.h" +#include "athena/test/base/test_util.h" #include "base/command_line.h" +#include "chrome/browser/profiles/profile_manager.h" #include "content/public/common/content_switches.h" namespace athena { -AthenaBrowserTest::AthenaBrowserTest() { +AthenaChromeBrowserTest::AthenaChromeBrowserTest() { } -AthenaBrowserTest::~AthenaBrowserTest() { +AthenaChromeBrowserTest::~AthenaChromeBrowserTest() { } -void AthenaBrowserTest::SetUpCommandLine(base::CommandLine* command_line) { +void AthenaChromeBrowserTest::SetUpCommandLine( + base::CommandLine* command_line) { // The NaCl sandbox won't work in our browser tests. command_line->AppendSwitch(switches::kNoSandbox); InProcessBrowserTest::SetUpCommandLine(command_line); } -void AthenaBrowserTest::SetUpOnMainThread() { +void AthenaChromeBrowserTest::SetUpOnMainThread() { // Set the memory pressure to low and turning off undeterministic resource // observer events. test_util::SendTestMemoryPressureEvent(ResourceManager::MEMORY_PRESSURE_LOW); } +content::BrowserContext* AthenaChromeBrowserTest::GetBrowserContext() { + return ProfileManager::GetActiveUserProfile(); +} + } // namespace athena diff --git a/athena/test/chrome/athena_browsertest.h b/athena/test/chrome/athena_chrome_browser_test.h index 85917e1e51..a16844a1c0 100644 --- a/athena/test/chrome/athena_browsertest.h +++ b/athena/test/chrome/athena_chrome_browser_test.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef ATHENA_TEST_CHROME_ATHENA_BROWSERTEST_H_ -#define ATHENA_TEST_CHROME_ATHENA_BROWSERTEST_H_ +#ifndef ATHENA_TEST_CHROME_ATHENA_CHROME_BROWSER_TEST_H_ +#define ATHENA_TEST_CHROME_ATHENA_CHROME_BROWSER_TEST_H_ #include "chrome/test/base/in_process_browser_test.h" @@ -11,27 +11,33 @@ namespace base { class CommandLine; } +namespace content { +class BrowserContext; +} + namespace athena { // Base class for athena tests which allows to use WebActivities. // // Note: To avoid asynchronous resource manager events, the memory pressure // callback gets turned off at the beginning to a low memory pressure. -class AthenaBrowserTest : public InProcessBrowserTest { +class AthenaChromeBrowserTest : public InProcessBrowserTest { public: - AthenaBrowserTest(); - ~AthenaBrowserTest() override; + AthenaChromeBrowserTest(); + ~AthenaChromeBrowserTest() override; protected: // BrowserTestBase: void SetUpCommandLine(base::CommandLine* command_line) override; void SetUpOnMainThread() override; + // Returns the browser context used by the test. + content::BrowserContext* GetBrowserContext(); + private: - DISALLOW_COPY_AND_ASSIGN(AthenaBrowserTest); + DISALLOW_COPY_AND_ASSIGN(AthenaChromeBrowserTest); }; } // namespace athena -#endif // ATHENA_TEST_CHROME_ATHENA_BROWSERTEST_H_ - +#endif // ATHENA_TEST_CHROME_ATHENA_CHROME_BROWSER_TEST_H_ |