Nukes view_manager_unittests I converted them over to apptests a while back. Now that we're running the apptests I can nuke this outdated test. BUG=none TEST=none R=viettrungluu@chromium.org Review URL: https://codereview.chromium.org/768883004
diff --git a/mojo/BUILD.gn b/mojo/BUILD.gn index fe74a7d..7dd4c19 100644 --- a/mojo/BUILD.gn +++ b/mojo/BUILD.gn
@@ -100,7 +100,6 @@ "//services/window_manager:window_manager_unittests", "//services/view_manager:view_manager_service_apptests", "//services/view_manager:view_manager_service_unittests", - "//services/view_manager:view_manager_unittests", ] }
diff --git a/mojo/tools/data/unittests b/mojo/tools/data/unittests index 1b178ba..d06279e 100644 --- a/mojo/tools/data/unittests +++ b/mojo/tools/data/unittests
@@ -21,7 +21,6 @@ # mojo_view_manager_lib_unittests mojo_surfaces_lib_unittests view_manager_service_unittests -view_manager_unittests window_manager_unittests # JavaScript tests:
diff --git a/services/view_manager/BUILD.gn b/services/view_manager/BUILD.gn index abc742d..1ad2555 100644 --- a/services/view_manager/BUILD.gn +++ b/services/view_manager/BUILD.gn
@@ -89,39 +89,6 @@ ] } -test("view_manager_unittests") { - sources = [ - "view_manager_unittest.cc", - ] - - deps = [ - ":test_support", - ":view_manager_lib", - "//base", - "//base/test:test_support", - "//mojo/application", - "//mojo/application_manager", - "//mojo/converters/geometry", - "//mojo/converters/input_events", - "//mojo/edk/system", - "//mojo/environment:chromium", - "//mojo/public/cpp/bindings", - "//mojo/services/public/cpp/native_viewport:args", - "//mojo/services/public/cpp/view_manager", - "//mojo/services/public/cpp/view_manager/lib:run_unittests", - "//mojo/services/public/interfaces/geometry", - "//mojo/services/public/interfaces/view_manager", - "//mojo/services/public/interfaces/window_manager", - "//mojo/shell:test_support", - "//testing/gtest", - "//ui/gfx/geometry", - ] - - if (!is_android) { # TODO(GYP) Enable on Android when osmesa links. - deps += [ "//third_party/mesa:osmesa" ] - } -} - test("view_manager_service_unittests") { sources = [ "view_coordinate_conversions_unittest.cc",
diff --git a/services/view_manager/view_manager_unittest.cc b/services/view_manager/view_manager_unittest.cc deleted file mode 100644 index afe9b8f..0000000 --- a/services/view_manager/view_manager_unittest.cc +++ /dev/null
@@ -1,1624 +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 <string> -#include <vector> - -#include "base/at_exit.h" -#include "base/auto_reset.h" -#include "base/bind.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/scoped_vector.h" -#include "base/message_loop/message_loop.h" -#include "base/run_loop.h" -#include "base/strings/stringprintf.h" -#include "mojo/application_manager/application_manager.h" -#include "mojo/common/common_type_converters.h" -#include "mojo/converters/geometry/geometry_type_converters.h" -#include "mojo/public/cpp/application/application_connection.h" -#include "mojo/public/cpp/application/application_delegate.h" -#include "mojo/public/cpp/application/application_impl.h" -#include "mojo/public/cpp/application/connect.h" -#include "mojo/public/cpp/application/interface_factory_impl.h" -#include "mojo/public/cpp/bindings/lib/router.h" -#include "mojo/public/interfaces/application/service_provider.mojom.h" -#include "mojo/services/public/cpp/native_viewport/args.h" -#include "mojo/services/public/cpp/view_manager/types.h" -#include "mojo/services/public/cpp/view_manager/util.h" -#include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h" -#include "mojo/services/public/interfaces/window_manager/window_manager.mojom.h" -#include "mojo/services/public/interfaces/window_manager/window_manager_internal.mojom.h" -#include "mojo/shell/shell_test_helper.h" -#include "services/view_manager/ids.h" -#include "services/view_manager/test_change_tracker.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "ui/gfx/geometry/rect.h" - -#if defined(OS_WIN) -#include "ui/gfx/win/window_impl.h" -#endif - -namespace mojo { -namespace service { - -namespace { - -const char kTestServiceURL[] = "mojo:test_url"; -const char kTestServiceURL2[] = "mojo:test_url2"; - -// ViewManagerProxy is a proxy to an ViewManagerService. It handles invoking -// ViewManagerService functions on the right thread in a synchronous manner -// (each ViewManagerService cover function blocks until the response from the -// ViewManagerService is returned). In addition it tracks the set of -// ViewManagerClient messages received by way of a vector of Changes. Use -// DoRunLoopUntilChangesCount() to wait for a certain number of messages to be -// received. -class ViewManagerProxy : public TestChangeTracker::Delegate { - public: - explicit ViewManagerProxy(TestChangeTracker* tracker) - : tracker_(tracker), - main_loop_(nullptr), - view_manager_(nullptr), - window_manager_client_(nullptr), - quit_count_(0), - router_(nullptr) { - } - - ~ViewManagerProxy() override {} - - // Returns true if in an initial state. If this returns false it means the - // last test didn't clean up properly, or most likely didn't invoke - // WaitForInstance() when it needed to. - static bool IsInInitialState() { return instance_ == NULL; } - - // Runs a message loop until the single instance has been created. - static ViewManagerProxy* WaitForInstance() { - if (!instance_ || !instance_->view_manager()) - RunMainLoop(); - ViewManagerProxy* instance = instance_; - instance_ = NULL; - return instance; - } - - ViewManagerService* view_manager() { return view_manager_; } - WindowManagerInternalClient* window_manager_client() { - return window_manager_client_; - } - - // Runs the main loop until |count| changes have been received. - std::vector<Change> DoRunLoopUntilChangesCount(size_t count) { - DCHECK_EQ(0u, quit_count_); - if (tracker_->changes()->size() >= count) { - CopyChangesFromTracker(); - return changes_; - } - quit_count_ = count - tracker_->changes()->size(); - // Run the current message loop. When |count| Changes have been received, - // we'll quit. - RunMainLoop(); - return changes_; - } - - const std::vector<Change>& changes() const { return changes_; } - - // Destroys the connection, blocking until done. - void Destroy() { - router_->CloseMessagePipe(); - } - - void ClearChanges() { - changes_.clear(); - tracker_->changes()->clear(); - } - - void CopyChangesFromTracker() { - std::vector<Change> changes; - tracker_->changes()->swap(changes); - changes_.swap(changes); - } - - // The following functions are cover methods for ViewManagerService. They - // block until the result is received. - bool CreateView(Id view_id) { - changes_.clear(); - ErrorCode result = ERROR_CODE_NONE; - view_manager_->CreateView( - view_id, - base::Bind(&ViewManagerProxy::GotResultWithErrorCode, - base::Unretained(this), - &result)); - RunMainLoop(); - return result == ERROR_CODE_NONE; - } - ErrorCode CreateViewWithErrorCode(Id view_id) { - changes_.clear(); - ErrorCode result = ERROR_CODE_NONE; - view_manager_->CreateView( - view_id, - base::Bind(&ViewManagerProxy::GotResultWithErrorCode, - base::Unretained(this), - &result)); - RunMainLoop(); - return result; - } - bool AddView(Id parent, Id child) { - changes_.clear(); - bool result = false; - view_manager_->AddView(parent, child, - base::Bind(&ViewManagerProxy::GotResult, - base::Unretained(this), &result)); - RunMainLoop(); - return result; - } - bool RemoveViewFromParent(Id view_id) { - changes_.clear(); - bool result = false; - view_manager_->RemoveViewFromParent( - view_id, - base::Bind( - &ViewManagerProxy::GotResult, base::Unretained(this), &result)); - RunMainLoop(); - return result; - } - bool ReorderView(Id view_id, Id relative_view_id, OrderDirection direction) { - changes_.clear(); - bool result = false; - view_manager_->ReorderView( - view_id, - relative_view_id, - direction, - base::Bind( - &ViewManagerProxy::GotResult, base::Unretained(this), &result)); - RunMainLoop(); - return result; - } - void GetViewTree(Id view_id, std::vector<TestView>* views) { - changes_.clear(); - view_manager_->GetViewTree( - view_id, - base::Bind( - &ViewManagerProxy::GotViewTree, base::Unretained(this), views)); - RunMainLoop(); - } - bool Embed(const Id view_id, const char* url) { - changes_.clear(); - base::AutoReset<bool> auto_reset(&in_embed_, true); - bool result = false; - ServiceProviderPtr services; - view_manager_->Embed( - url, - view_id, - MakeRequest<ServiceProvider>(services.PassMessagePipe()), - base::Bind( - &ViewManagerProxy::GotResult, base::Unretained(this), &result)); - RunMainLoop(); - return result; - } - bool DeleteView(Id view_id) { - changes_.clear(); - bool result = false; - view_manager_->DeleteView( - view_id, - base::Bind( - &ViewManagerProxy::GotResult, base::Unretained(this), &result)); - RunMainLoop(); - return result; - } - bool SetViewBounds(Id view_id, const gfx::Rect& bounds) { - changes_.clear(); - bool result = false; - view_manager_->SetViewBounds( - view_id, - Rect::From(bounds), - base::Bind( - &ViewManagerProxy::GotResult, base::Unretained(this), &result)); - RunMainLoop(); - return result; - } - bool SetViewVisibility(Id view_id, bool visible) { - changes_.clear(); - bool result = false; - view_manager_->SetViewVisibility( - view_id, - visible, - base::Bind( - &ViewManagerProxy::GotResult, base::Unretained(this), &result)); - RunMainLoop(); - return result; - } - bool SetViewProperty(Id view_id, const std::string& name, - const std::vector<uint8_t>* data) { - changes_.clear(); - bool result = false; - Array<uint8_t> mojo_data; - if (data) - mojo_data = Array<uint8_t>::From(*data); - view_manager_->SetViewProperty( - view_id, - name, - mojo_data.Pass(), - base::Bind( - &ViewManagerProxy::GotResult, base::Unretained(this), &result)); - RunMainLoop(); - return result; - } - - void set_view_manager(ViewManagerService* view_manager) { - view_manager_ = view_manager; - SetInstance(this); - } - - private: - friend class TestViewManagerClientConnection; - friend class TestWindowManagerImpl; - - void set_router(mojo::internal::Router* router) { router_ = router; } - - void set_window_manager_client(WindowManagerInternalClient* client) { - window_manager_client_ = client; - } - - static void RunMainLoop() { - DCHECK(!main_run_loop_); - main_run_loop_ = new base::RunLoop; - main_run_loop_->Run(); - delete main_run_loop_; - main_run_loop_ = NULL; - } - - void QuitCountReached() { - CopyChangesFromTracker(); - main_run_loop_->Quit(); - } - - static void SetInstance(ViewManagerProxy* instance) { - DCHECK(!instance_); - instance_ = instance; - // Embed() runs its own run loop that is quit when the result is - // received. Embed() also results in a new instance. If we quit here while - // waiting for a Embed() we would prematurely return before we got the - // result from Embed(). - if (!in_embed_ && main_run_loop_) - main_run_loop_->Quit(); - } - - // Callbacks from the various ViewManagerService functions. - void GotResult(bool* result_cache, bool result) { - *result_cache = result; - DCHECK(main_run_loop_); - main_run_loop_->Quit(); - } - - void GotResultWithErrorCode(ErrorCode* error_code_cache, - ErrorCode error_code) { - *error_code_cache = error_code; - DCHECK(main_run_loop_); - main_run_loop_->Quit(); - } - - void GotViewTree(std::vector<TestView>* views, Array<ViewDataPtr> results) { - ViewDatasToTestViews(results, views); - DCHECK(main_run_loop_); - main_run_loop_->Quit(); - } - - // TestChangeTracker::Delegate: - void OnChangeAdded() override { - if (quit_count_ > 0 && --quit_count_ == 0) - QuitCountReached(); - } - - static ViewManagerProxy* instance_; - static base::RunLoop* main_run_loop_; - static bool in_embed_; - - TestChangeTracker* tracker_; - - // MessageLoop of the test. - base::MessageLoop* main_loop_; - - ViewManagerService* view_manager_; - WindowManagerInternalClient* window_manager_client_; - - // Number of changes we're waiting on until we quit the current loop. - size_t quit_count_; - - std::vector<Change> changes_; - - mojo::internal::Router* router_; - - DISALLOW_COPY_AND_ASSIGN(ViewManagerProxy); -}; - -// static -ViewManagerProxy* ViewManagerProxy::instance_ = NULL; - -// static -base::RunLoop* ViewManagerProxy::main_run_loop_ = NULL; - -// static -bool ViewManagerProxy::in_embed_ = false; - -class TestViewManagerClientConnection - : public InterfaceImpl<ViewManagerClient> { - public: - TestViewManagerClientConnection() : proxy_(&tracker_) { - tracker_.set_delegate(&proxy_); - } - - TestChangeTracker* tracker() { return &tracker_; } - - ViewManagerProxy* proxy() { return &proxy_; } - - void OnConnectionEstablished() { - proxy_.set_router(internal_router()); - proxy_.set_view_manager(client()); - } - - // ViewManagerClient: - void OnEmbed(ConnectionSpecificId connection_id, - const String& creator_url, - ViewDataPtr root, - InterfaceRequest<ServiceProvider> services, - ScopedMessagePipeHandle window_manager_pipe) override { - tracker()->OnEmbed(connection_id, creator_url, root.Pass()); - } - void OnEmbeddedAppDisconnected(Id view_id) override { - // Coverage of this is in view_manager_server_apptest. - } - void OnViewBoundsChanged(Id view_id, - RectPtr old_bounds, - RectPtr new_bounds) override { - tracker()->OnViewBoundsChanged( - view_id, old_bounds.Pass(), new_bounds.Pass()); - } - void OnViewHierarchyChanged(Id view, - Id new_parent, - Id old_parent, - Array<ViewDataPtr> views) override { - tracker()->OnViewHierarchyChanged( - view, new_parent, old_parent, views.Pass()); - } - void OnViewReordered(Id view_id, - Id relative_view_id, - OrderDirection direction) override { - tracker()->OnViewReordered(view_id, relative_view_id, direction); - } - void OnViewDeleted(Id view) override { tracker()->OnViewDeleted(view); } - void OnViewVisibilityChanged(uint32_t view, bool visible) override { - tracker()->OnViewVisibilityChanged(view, visible); - } - void OnViewDrawnStateChanged(uint32_t view, bool drawn) override { - tracker()->OnViewDrawnStateChanged(view, drawn); - } - void OnViewInputEvent(Id view_id, - EventPtr event, - const Callback<void()>& callback) override { - tracker()->OnViewInputEvent(view_id, event.Pass()); - } - void OnViewSharedPropertyChanged(uint32_t view, - const String& name, - Array<uint8_t> new_data) override { - tracker_.OnViewSharedPropertyChanged(view, name, new_data.Pass()); - } - - private: - TestChangeTracker tracker_; - ViewManagerProxy proxy_; - - DISALLOW_COPY_AND_ASSIGN(TestViewManagerClientConnection); -}; - -// Used with ViewManagerService::Embed(). Creates a -// TestViewManagerClientConnection, which creates and owns the ViewManagerProxy. -class EmbedApplicationLoader : public ApplicationLoader, - ApplicationDelegate, - public InterfaceFactory<ViewManagerClient> { - public: - EmbedApplicationLoader() {} - ~EmbedApplicationLoader() override {} - - // ApplicationLoader implementation: - void Load(ApplicationManager* manager, - const GURL& url, - ScopedMessagePipeHandle shell_handle, - LoadCallback callback) override { - ASSERT_TRUE(shell_handle.is_valid()); - scoped_ptr<ApplicationImpl> app( - new ApplicationImpl(this, shell_handle.Pass())); - apps_.push_back(app.release()); - } - void OnApplicationError(ApplicationManager* manager, - const GURL& url) override {} - - // ApplicationDelegate implementation: - bool ConfigureIncomingConnection(ApplicationConnection* connection) override { - connection->AddService<ViewManagerClient>(this); - return true; - } - - // InterfaceFactory<ViewManagerClient> implementation: - void Create(ApplicationConnection* connection, - InterfaceRequest<ViewManagerClient> request) override { - auto client_connection = new TestViewManagerClientConnection; - BindToRequest(client_connection, &request); - client_connection->OnConnectionEstablished(); - } - - private: - ScopedVector<ApplicationImpl> apps_; - - DISALLOW_COPY_AND_ASSIGN(EmbedApplicationLoader); -}; - -class TestWindowManagerImpl : public InterfaceImpl<WindowManager> { - public: - explicit TestWindowManagerImpl(ApplicationConnection* connection) - : view_manager_client_(nullptr), got_initial_embed_(false) { - // WindowManager is expected to establish initial connection to VM. - ApplicationConnection* view_manager_app = - connection->ConnectToApplication("mojo:view_manager"); - view_manager_app->ConnectToService(&view_manager_); - view_manager_app->ConnectToService(&window_manager_client_); - - view_manager_client_ = new TestViewManagerClientConnection(); - view_manager_.set_client(view_manager_client_); - view_manager_client_->proxy()->set_window_manager_client( - window_manager_client_.get()); - view_manager_client_->proxy()->set_view_manager(view_manager_.get()); - } - - virtual ~TestWindowManagerImpl() {} - - TestViewManagerClientConnection* view_manager_client() { - return view_manager_client_; - } - - // WindowManager: - void Embed(const String& url, - InterfaceRequest<ServiceProvider> service_provider) override { - if (!got_initial_embed_) { - got_initial_embed_ = true; - return; - } - view_manager_client_->tracker()->DelegateEmbed(url); - } - void SetCapture(Id view, const Callback<void(bool)>& callback) override { - callback.Run(true); - } - void FocusWindow(Id view, const Callback<void(bool)>& callback) override { - callback.Run(true); - } - void ActivateWindow(Id view, const Callback<void(bool)>& callback) override { - callback.Run(true); - } - - private: - ViewManagerServicePtr view_manager_; - TestViewManagerClientConnection* view_manager_client_; - WindowManagerInternalClientPtr window_manager_client_; - - // Did we get Embed() yet? - bool got_initial_embed_; - - DISALLOW_COPY_AND_ASSIGN(TestWindowManagerImpl); -}; - -class WindowManagerLoader : public ApplicationLoader, - public ApplicationDelegate, - public InterfaceFactory<WindowManager> { - public: - explicit WindowManagerLoader(EmbedApplicationLoader* app_loader) - : app_loader_(app_loader) {} - virtual ~WindowManagerLoader() {} - - // ApplicationLoader implementation: - virtual void Load(ApplicationManager* manager, - const GURL& url, - ScopedMessagePipeHandle shell_handle, - LoadCallback callback) override { - ASSERT_TRUE(shell_handle.is_valid()); - scoped_ptr<ApplicationImpl> app( - new ApplicationImpl(this, shell_handle.Pass())); - apps_.push_back(app.release()); - } - virtual void OnApplicationError(ApplicationManager* manager, - const GURL& url) override {} - - // ApplicationDelegate implementation: - virtual bool ConfigureIncomingConnection( - ApplicationConnection* connection) override { - connection->AddService<WindowManager>(this); - return true; - } - - // InterfaceFactory<WindowManagerService>: - virtual void Create(ApplicationConnection* connection, - InterfaceRequest<WindowManager> request) override { - TestWindowManagerImpl* window_manager = - new TestWindowManagerImpl(connection); - BindToRequest(window_manager, &request); - } - - private: - // TODO: unused. - EmbedApplicationLoader* app_loader_; - ScopedVector<ApplicationImpl> apps_; - - DISALLOW_COPY_AND_ASSIGN(WindowManagerLoader); -}; - -// Creates an id used for transport from the specified parameters. -Id BuildViewId(ConnectionSpecificId connection_id, - ConnectionSpecificId view_id) { - return (connection_id << 16) | view_id; -} - -// Asks the window manager to Embed() the specified URL. -void WindowManagerEmbed(WindowManager* window_manager, - const std::string& url, - size_t number_of_calls) { - for (size_t i = 0; i < number_of_calls; ++i) { - ServiceProviderPtr sp; - window_manager->Embed(url, - MakeRequest<ServiceProvider>(sp.PassMessagePipe())); - } -} - -} // namespace - -typedef std::vector<std::string> Changes; - -class ViewManagerTest : public testing::Test { - public: - ViewManagerTest() - : connection_(NULL), - connection2_(NULL), - connection3_(NULL) {} - - void SetUp() override { - ASSERT_TRUE(ViewManagerProxy::IsInInitialState()); - test_helper_.Init(); - std::vector<std::string> native_viewport_args; - native_viewport_args.push_back(kUseTestConfig); - test_helper_.application_manager()->SetArgsForURL( - native_viewport_args, GURL("mojo:native_viewport_service")); - -#if defined(OS_WIN) - // As we unload the wndproc of window classes we need to be sure to - // unregister them. - gfx::WindowImpl::UnregisterClassesAtExit(); -#endif - - test_helper_.SetLoaderForURL( - scoped_ptr<ApplicationLoader>(new EmbedApplicationLoader()), - GURL(kTestServiceURL)); - - EmbedApplicationLoader* embed_loader = new EmbedApplicationLoader; - test_helper_.SetLoaderForURL(scoped_ptr<ApplicationLoader>(embed_loader), - GURL(kTestServiceURL2)); - - test_helper_.SetLoaderForURL( - scoped_ptr<ApplicationLoader>(new WindowManagerLoader(embed_loader)), - GURL("mojo:window_manager")); - - test_helper_.application_manager()->ConnectToService( - GURL("mojo:window_manager"), &window_manager_); - WindowManagerEmbed(window_manager_.get(), kTestServiceURL, 1); - - connection_ = ViewManagerProxy::WaitForInstance(); - ASSERT_TRUE(connection_ != NULL); - connection_->DoRunLoopUntilChangesCount(1); - } - - void TearDown() override { - if (connection3_) - connection3_->Destroy(); - if (connection2_) - connection2_->Destroy(); - // |connection_| is owned by |window_manager_|, no need to destroy it. - } - - protected: - void EstablishSecondConnectionWithRoot(Id root_id) { - ASSERT_TRUE(connection_->Embed(root_id, kTestServiceURL)); - connection2_ = ViewManagerProxy::WaitForInstance(); - ASSERT_TRUE(connection2_ != NULL); - connection2_->DoRunLoopUntilChangesCount(1); - ASSERT_EQ(1u, connection2_->changes().size()); - } - - // Creates a second connection to the viewmanager. - void EstablishSecondConnection(bool create_initial_view) { - if (create_initial_view) - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1))); - ASSERT_NO_FATAL_FAILURE( - EstablishSecondConnectionWithRoot(BuildViewId(1, 1))); - const std::vector<Change>& changes(connection2_->changes()); - ASSERT_EQ(1u, changes.size()); - EXPECT_EQ("OnEmbed creator=mojo:window_manager", - ChangesToDescription1(changes)[0]); - if (create_initial_view) - EXPECT_EQ("[view=1,1 parent=null]", ChangeViewDescription(changes)); - } - - void EstablishThirdConnection(ViewManagerProxy* owner, Id root_id) { - ASSERT_TRUE(connection3_ == NULL); - ASSERT_TRUE(owner->Embed(root_id, kTestServiceURL2)); - connection3_ = ViewManagerProxy::WaitForInstance(); - ASSERT_TRUE(connection3_ != NULL); - connection3_->DoRunLoopUntilChangesCount(1); - ASSERT_EQ(1u, connection3_->changes().size()); - const std::string expected_creator = - owner == connection_ ? "mojo:window_manager" : kTestServiceURL; - EXPECT_EQ("OnEmbed creator=" + expected_creator, - ChangesToDescription1(connection3_->changes())[0]); - } - - void DestroySecondConnection() { - connection2_->Destroy(); - connection2_ = NULL; - } - - base::ShadowingAtExitManager at_exit_; - shell::ShellTestHelper test_helper_; - - WindowManagerPtr window_manager_; - - // NOTE: this connection is the root. As such, it has special permissions. - ViewManagerProxy* connection_; - ViewManagerProxy* connection2_; - ViewManagerProxy* connection3_; - - DISALLOW_COPY_AND_ASSIGN(ViewManagerTest); -}; - -TEST_F(ViewManagerTest, SecondEmbedRoot_InitService) { - WindowManagerEmbed(window_manager_.get(), kTestServiceURL, 1); - connection_->DoRunLoopUntilChangesCount(1); - EXPECT_EQ(kTestServiceURL, connection_->changes()[0].embed_url); -} - -TEST_F(ViewManagerTest, MultipleEmbedRootsBeforeWTHReady) { - WindowManagerEmbed(window_manager_.get(), kTestServiceURL, 2); - connection_->DoRunLoopUntilChangesCount(2); - EXPECT_EQ(kTestServiceURL, connection_->changes()[0].embed_url); - EXPECT_EQ(kTestServiceURL, connection_->changes()[1].embed_url); -} - -// Verifies client gets a valid id. -// http://crbug.com/396492 -TEST_F(ViewManagerTest, DISABLED_ValidId) { - // TODO(beng): this should really have the URL of the application that - // connected to ViewManagerInit. - EXPECT_EQ("OnEmbed creator=", - ChangesToDescription1(connection_->changes())[0]); - - // All these tests assume 1 for the client id. The only real assertion here is - // the client id is not zero, but adding this as rest of code here assumes 1. - EXPECT_EQ(1, connection_->changes()[0].connection_id); -} - -// Verifies two clients/connections get different ids. -TEST_F(ViewManagerTest, TwoClientsGetDifferentConnectionIds) { - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); - EXPECT_EQ("OnEmbed creator=mojo:window_manager", - ChangesToDescription1(connection2_->changes())[0]); - - // It isn't strictly necessary that the second connection gets 2, but these - // tests are written assuming that is the case. The key thing is the - // connection ids of |connection_| and |connection2_| differ. - EXPECT_EQ(2, connection2_->changes()[0].connection_id); -} - -// Verifies when Embed() is invoked any child views are removed. -TEST_F(ViewManagerTest, ViewsRemovedWhenEmbedding) { - // Two views 1 and 2. 2 is parented to 1. - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1))); - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2))); - ASSERT_TRUE(connection_->AddView(BuildViewId(1, 1), BuildViewId(1, 2))); - - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); - EXPECT_EQ("[view=1,1 parent=null]", - ChangeViewDescription(connection2_->changes())); - - // Embed() removed view 2. - { - std::vector<TestView> views; - connection_->GetViewTree(BuildViewId(1, 2), &views); - ASSERT_EQ(1u, views.size()); - EXPECT_EQ("view=1,2 parent=null", views[0].ToString()); - } - - // |connection2_| should not see view 2. - { - std::vector<TestView> views; - connection2_->GetViewTree(BuildViewId(1, 1), &views); - ASSERT_EQ(1u, views.size()); - EXPECT_EQ("view=1,1 parent=null", views[0].ToString()); - } - { - std::vector<TestView> views; - connection2_->GetViewTree(BuildViewId(1, 2), &views); - EXPECT_TRUE(views.empty()); - } - - // Views 3 and 4 in connection 2. - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 3))); - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 4))); - ASSERT_TRUE(connection2_->AddView(BuildViewId(2, 3), BuildViewId(2, 4))); - - // Connection 3 rooted at 2. - ASSERT_NO_FATAL_FAILURE( - EstablishThirdConnection(connection2_, BuildViewId(2, 3))); - - // View 4 should no longer have a parent. - { - std::vector<TestView> views; - connection2_->GetViewTree(BuildViewId(2, 3), &views); - ASSERT_EQ(1u, views.size()); - EXPECT_EQ("view=2,3 parent=null", views[0].ToString()); - - views.clear(); - connection2_->GetViewTree(BuildViewId(2, 4), &views); - ASSERT_EQ(1u, views.size()); - EXPECT_EQ("view=2,4 parent=null", views[0].ToString()); - } - - // And view 4 should not be visible to connection 3. - { - std::vector<TestView> views; - connection3_->GetViewTree(BuildViewId(2, 3), &views); - ASSERT_EQ(1u, views.size()); - EXPECT_EQ("view=2,3 parent=null", views[0].ToString()); - } -} - -// Verifies once Embed() has been invoked the parent connection can't see any -// children. -TEST_F(ViewManagerTest, CantAccessChildrenOfEmbeddedView) { - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); - - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 2))); - ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 2))); - - ASSERT_NO_FATAL_FAILURE( - EstablishThirdConnection(connection2_, BuildViewId(2, 2))); - - ASSERT_TRUE(connection3_->CreateView(BuildViewId(3, 3))); - ASSERT_TRUE(connection3_->AddView(BuildViewId(2, 2), BuildViewId(3, 3))); - - // Even though 3 is a child of 2 connection 2 can't see 3 as it's from a - // different connection. - { - std::vector<TestView> views; - connection2_->GetViewTree(BuildViewId(2, 2), &views); - ASSERT_EQ(1u, views.size()); - EXPECT_EQ("view=2,2 parent=1,1", views[0].ToString()); - } - - { - std::vector<TestView> views; - connection2_->GetViewTree(BuildViewId(3, 3), &views); - EXPECT_TRUE(views.empty()); - } - - // Connection 2 shouldn't be able to get view 3 at all. - { - std::vector<TestView> views; - connection2_->GetViewTree(BuildViewId(3, 3), &views); - EXPECT_TRUE(views.empty()); - } - - // Connection 1 should be able to see it all (its the root). - { - std::vector<TestView> views; - connection_->GetViewTree(BuildViewId(1, 1), &views); - ASSERT_EQ(3u, views.size()); - EXPECT_EQ("view=1,1 parent=null", views[0].ToString()); - EXPECT_EQ("view=2,2 parent=1,1", views[1].ToString()); - EXPECT_EQ("view=3,3 parent=2,2", views[2].ToString()); - } -} - -// Verifies once Embed() has been invoked the parent can't mutate the children. -TEST_F(ViewManagerTest, CantModifyChildrenOfEmbeddedView) { - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); - - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 2))); - ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 2))); - - ASSERT_NO_FATAL_FAILURE( - EstablishThirdConnection(connection2_, BuildViewId(2, 2))); - - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 3))); - // Connection 2 shouldn't be able to add anything to the view anymore. - ASSERT_FALSE(connection2_->AddView(BuildViewId(2, 2), BuildViewId(2, 3))); - - // Create view 3 in connection 3 and add it to view 3. - ASSERT_TRUE(connection3_->CreateView(BuildViewId(3, 3))); - ASSERT_TRUE(connection3_->AddView(BuildViewId(2, 2), BuildViewId(3, 3))); - - // Connection 2 shouldn't be able to remove view 3. - ASSERT_FALSE(connection2_->RemoveViewFromParent(BuildViewId(3, 3))); -} - -// Verifies client gets a valid id. -TEST_F(ViewManagerTest, CreateView) { - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1))); - EXPECT_TRUE(connection_->changes().empty()); - - // Can't create a view with the same id. - ASSERT_EQ(ERROR_CODE_VALUE_IN_USE, - connection_->CreateViewWithErrorCode(BuildViewId(1, 1))); - EXPECT_TRUE(connection_->changes().empty()); - - // Can't create a view with a bogus connection id. - EXPECT_EQ(ERROR_CODE_ILLEGAL_ARGUMENT, - connection_->CreateViewWithErrorCode(BuildViewId(2, 1))); - EXPECT_TRUE(connection_->changes().empty()); -} - -// Verifies AddView fails when view is already in position. -TEST_F(ViewManagerTest, AddViewWithNoChange) { - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2))); - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 3))); - - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); - - // Make 3 a child of 2. - ASSERT_TRUE(connection_->AddView(BuildViewId(1, 2), BuildViewId(1, 3))); - - // Try again, this should fail. - EXPECT_FALSE(connection_->AddView(BuildViewId(1, 2), BuildViewId(1, 3))); -} - -// Verifies AddView fails when view is already in position. -TEST_F(ViewManagerTest, AddAncestorFails) { - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2))); - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 3))); - - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); - - // Make 3 a child of 2. - ASSERT_TRUE(connection_->AddView(BuildViewId(1, 2), BuildViewId(1, 3))); - - // Try to make 2 a child of 3, this should fail since 2 is an ancestor of 3. - EXPECT_FALSE(connection_->AddView(BuildViewId(1, 3), BuildViewId(1, 2))); -} - -// Verifies adding to root sends right notifications. -TEST_F(ViewManagerTest, AddToRoot) { - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 21))); - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 3))); - - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); - - // Make 3 a child of 21. - ASSERT_TRUE(connection_->AddView(BuildViewId(1, 21), BuildViewId(1, 3))); - - // Make 21 a child of 1. - ASSERT_TRUE(connection_->AddView(BuildViewId(1, 1), BuildViewId(1, 21))); - - // Connection 2 should not be told anything (because the view is from a - // different connection). Create a view to ensure we got a response from - // the server. - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 100))); - connection2_->CopyChangesFromTracker(); - EXPECT_TRUE(connection2_->changes().empty()); -} - -// Verifies HierarchyChanged is correctly sent for various adds/removes. -TEST_F(ViewManagerTest, ViewHierarchyChangedViews) { - // 1,2->1,11. - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2))); - ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 2), true)); - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 11))); - ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 11), true)); - ASSERT_TRUE(connection_->AddView(BuildViewId(1, 2), BuildViewId(1, 11))); - - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); - ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 1), true)); - - // 1,1->1,2->1,11 - { - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 101))); - // Client 2 should not get anything (1,2 is from another connection). - connection2_->ClearChanges(); - ASSERT_TRUE(connection_->AddView(BuildViewId(1, 1), BuildViewId(1, 2))); - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 100))); - connection2_->CopyChangesFromTracker(); - EXPECT_TRUE(connection2_->changes().empty()); - } - - // 0,1->1,1->1,2->1,11. - { - // Client 2 is now connected to the root, so it should have gotten a drawn - // notification. - ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1))); - connection2_->DoRunLoopUntilChangesCount(1); - ASSERT_EQ(1u, connection2_->changes().size()); - EXPECT_EQ("DrawnStateChanged view=1,1 drawn=true", - ChangesToDescription1(connection2_->changes())[0]); - } - - // 1,1->1,2->1,11. - { - // Client 2 is no longer connected to the root, should get drawn state - // changed. - ASSERT_TRUE(connection_->RemoveViewFromParent(BuildViewId(1, 1))); - connection2_->DoRunLoopUntilChangesCount(1); - ASSERT_EQ(1u, connection2_->changes().size()); - EXPECT_EQ("DrawnStateChanged view=1,1 drawn=false", - ChangesToDescription1(connection2_->changes())[0]); - } - - // 1,1->1,2->1,11->1,111. - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 111))); - ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 111), true)); - { - connection2_->ClearChanges(); - ASSERT_TRUE(connection_->AddView(BuildViewId(1, 11), BuildViewId(1, 111))); - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 103))); - connection2_->CopyChangesFromTracker(); - EXPECT_TRUE(connection2_->changes().empty()); - } - - // 0,1->1,1->1,2->1,11->1,111 - { - connection2_->ClearChanges(); - ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1))); - connection2_->DoRunLoopUntilChangesCount(1); - ASSERT_EQ(1u, connection2_->changes().size()); - EXPECT_EQ("DrawnStateChanged view=1,1 drawn=true", - ChangesToDescription1(connection2_->changes())[0]); - } -} - -TEST_F(ViewManagerTest, ViewHierarchyChangedAddingKnownToUnknown) { - // Create the following structure: root -> 1 -> 11 and 2->21 (2 has no - // parent). - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); - - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 11))); - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 2))); - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 21))); - - // Set up the hierarchy. - ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1))); - ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 11))); - ASSERT_TRUE(connection2_->AddView(BuildViewId(2, 2), BuildViewId(2, 21))); - - // Remove 11, should result in a hierarchy change for the root. - { - connection_->ClearChanges(); - ASSERT_TRUE(connection2_->RemoveViewFromParent(BuildViewId(2, 11))); - - connection_->DoRunLoopUntilChangesCount(1); - const Changes changes(ChangesToDescription1(connection_->changes())); - ASSERT_EQ(1u, changes.size()); - EXPECT_EQ("HierarchyChanged view=2,11 new_parent=null old_parent=1,1", - changes[0]); - } - - // Add 2 to 1. - { - ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 2))); - - connection_->DoRunLoopUntilChangesCount(1); - const Changes changes(ChangesToDescription1(connection_->changes())); - ASSERT_EQ(1u, changes.size()); - EXPECT_EQ("HierarchyChanged view=2,2 new_parent=1,1 old_parent=null", - changes[0]); - EXPECT_EQ( - "[view=2,2 parent=1,1]," - "[view=2,21 parent=2,2]", - ChangeViewDescription(connection_->changes())); - } -} - -TEST_F(ViewManagerTest, ReorderView) { - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); - - Id view1_id = BuildViewId(2, 1); - Id view2_id = BuildViewId(2, 2); - Id view3_id = BuildViewId(2, 3); - Id view4_id = BuildViewId(1, 4); // Peer to 1,1 - Id view5_id = BuildViewId(1, 5); // Peer to 1,1 - Id view6_id = BuildViewId(2, 6); // Child of 1,2. - Id view7_id = BuildViewId(2, 7); // Unparented. - Id view8_id = BuildViewId(2, 8); // Unparented. - ASSERT_TRUE(connection2_->CreateView(view1_id)); - ASSERT_TRUE(connection2_->CreateView(view2_id)); - ASSERT_TRUE(connection2_->CreateView(view3_id)); - ASSERT_TRUE(connection_->CreateView(view4_id)); - ASSERT_TRUE(connection_->CreateView(view5_id)); - ASSERT_TRUE(connection2_->CreateView(view6_id)); - ASSERT_TRUE(connection2_->CreateView(view7_id)); - ASSERT_TRUE(connection2_->CreateView(view8_id)); - ASSERT_TRUE(connection2_->AddView(view1_id, view2_id)); - ASSERT_TRUE(connection2_->AddView(view2_id, view6_id)); - ASSERT_TRUE(connection2_->AddView(view1_id, view3_id)); - ASSERT_TRUE( - connection_->AddView(ViewIdToTransportId(RootViewId()), view4_id)); - ASSERT_TRUE( - connection_->AddView(ViewIdToTransportId(RootViewId()), view5_id)); - - ASSERT_TRUE( - connection_->AddView(ViewIdToTransportId(RootViewId()), view1_id)); - - { - ASSERT_TRUE( - connection2_->ReorderView(view2_id, view3_id, ORDER_DIRECTION_ABOVE)); - - connection_->DoRunLoopUntilChangesCount(1); - const Changes changes(ChangesToDescription1(connection_->changes())); - ASSERT_EQ(1u, changes.size()); - EXPECT_EQ("Reordered view=2,2 relative=2,3 direction=above", changes[0]); - } - - { - ASSERT_TRUE( - connection2_->ReorderView(view2_id, view3_id, ORDER_DIRECTION_BELOW)); - - connection_->DoRunLoopUntilChangesCount(1); - const Changes changes(ChangesToDescription1(connection_->changes())); - ASSERT_EQ(1u, changes.size()); - EXPECT_EQ("Reordered view=2,2 relative=2,3 direction=below", changes[0]); - } - - // view2 is already below view3. - EXPECT_FALSE( - connection2_->ReorderView(view2_id, view3_id, ORDER_DIRECTION_BELOW)); - - // view4 & 5 are unknown to connection2_. - EXPECT_FALSE( - connection2_->ReorderView(view4_id, view5_id, ORDER_DIRECTION_ABOVE)); - - // view6 & view3 have different parents. - EXPECT_FALSE( - connection_->ReorderView(view3_id, view6_id, ORDER_DIRECTION_ABOVE)); - - // Non-existent view-ids - EXPECT_FALSE(connection_->ReorderView( - BuildViewId(1, 27), BuildViewId(1, 28), ORDER_DIRECTION_ABOVE)); - - // view7 & view8 are un-parented. - EXPECT_FALSE( - connection_->ReorderView(view7_id, view8_id, ORDER_DIRECTION_ABOVE)); -} - -// Verifies DeleteView works. -TEST_F(ViewManagerTest, DeleteView) { - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 2))); - - // Make 2 a child of 1. - { - ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 2))); - connection_->DoRunLoopUntilChangesCount(1); - const Changes changes(ChangesToDescription1(connection_->changes())); - ASSERT_EQ(1u, changes.size()); - EXPECT_EQ("HierarchyChanged view=2,2 new_parent=1,1 old_parent=null", - changes[0]); - } - - // Delete 2. - { - ASSERT_TRUE(connection2_->DeleteView(BuildViewId(2, 2))); - EXPECT_TRUE(connection2_->changes().empty()); - - connection_->DoRunLoopUntilChangesCount(1); - const Changes changes(ChangesToDescription1(connection_->changes())); - ASSERT_EQ(1u, changes.size()); - EXPECT_EQ("ViewDeleted view=2,2", changes[0]); - } -} - -// Verifies DeleteView isn't allowed from a separate connection. -TEST_F(ViewManagerTest, DeleteViewFromAnotherConnectionDisallowed) { - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); - EXPECT_FALSE(connection2_->DeleteView(BuildViewId(1, 1))); -} - -// Verifies if a view was deleted and then reused that other clients are -// properly notified. -TEST_F(ViewManagerTest, ReuseDeletedViewId) { - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 2))); - - // Add 2 to 1. - { - ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 2))); - - connection_->DoRunLoopUntilChangesCount(1); - const Changes changes(ChangesToDescription1(connection_->changes())); - EXPECT_EQ("HierarchyChanged view=2,2 new_parent=1,1 old_parent=null", - changes[0]); - EXPECT_EQ("[view=2,2 parent=1,1]", - ChangeViewDescription(connection_->changes())); - } - - // Delete 2. - { - ASSERT_TRUE(connection2_->DeleteView(BuildViewId(2, 2))); - - connection_->DoRunLoopUntilChangesCount(1); - const Changes changes(ChangesToDescription1(connection_->changes())); - ASSERT_EQ(1u, changes.size()); - EXPECT_EQ("ViewDeleted view=2,2", changes[0]); - } - - // Create 2 again, and add it back to 1. Should get the same notification. - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 2))); - { - ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 2))); - - connection_->DoRunLoopUntilChangesCount(1); - const Changes changes(ChangesToDescription1(connection_->changes())); - EXPECT_EQ("HierarchyChanged view=2,2 new_parent=1,1 old_parent=null", - changes[0]); - EXPECT_EQ("[view=2,2 parent=1,1]", - ChangeViewDescription(connection_->changes())); - } -} - -// Assertions for GetViewTree. -TEST_F(ViewManagerTest, GetViewTree) { - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); - - // Create 11 in first connection and make it a child of 1. - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 11))); - ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1))); - ASSERT_TRUE(connection_->AddView(BuildViewId(1, 1), BuildViewId(1, 11))); - - // Create two views in second connection, 2 and 3, both children of 1. - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 2))); - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 3))); - ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 2))); - ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(2, 3))); - - // Verifies GetViewTree() on the root. The root connection sees all. - { - std::vector<TestView> views; - connection_->GetViewTree(BuildViewId(0, 1), &views); - ASSERT_EQ(5u, views.size()); - EXPECT_EQ("view=0,1 parent=null", views[0].ToString()); - EXPECT_EQ("view=1,1 parent=0,1", views[1].ToString()); - EXPECT_EQ("view=1,11 parent=1,1", views[2].ToString()); - EXPECT_EQ("view=2,2 parent=1,1", views[3].ToString()); - EXPECT_EQ("view=2,3 parent=1,1", views[4].ToString()); - } - - // Verifies GetViewTree() from connection2 for 1,1. connection2 should see 1,1 - // as 1,1 is the root for connection2 and all of 1,1's children as connection2 - // created them. - { - std::vector<TestView> views; - connection2_->GetViewTree(BuildViewId(1, 1), &views); - ASSERT_EQ(3u, views.size()); - EXPECT_EQ("view=1,1 parent=null", views[0].ToString()); - EXPECT_EQ("view=2,2 parent=1,1", views[1].ToString()); - EXPECT_EQ("view=2,3 parent=1,1", views[2].ToString()); - } - - // Connection 2 shouldn't be able to get the root tree. - { - std::vector<TestView> views; - connection2_->GetViewTree(BuildViewId(0, 1), &views); - ASSERT_EQ(0u, views.size()); - } -} - -TEST_F(ViewManagerTest, SetViewBounds) { - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1))); - ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1))); - - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); - - ASSERT_TRUE( - connection_->SetViewBounds(BuildViewId(1, 1), gfx::Rect(0, 0, 100, 100))); - - connection2_->DoRunLoopUntilChangesCount(1); - const Changes changes(ChangesToDescription1(connection2_->changes())); - ASSERT_EQ(1u, changes.size()); - EXPECT_EQ("BoundsChanged view=1,1 old_bounds=0,0 0x0 new_bounds=0,0 100x100", - changes[0]); - - // Should not be possible to change the bounds of a view created by another - // connection. - ASSERT_FALSE( - connection2_->SetViewBounds(BuildViewId(1, 1), gfx::Rect(0, 0, 0, 0))); -} - -// Verify AddView fails when trying to manipulate views in other roots. -TEST_F(ViewManagerTest, CantMoveViewsFromOtherRoot) { - // Create 1 and 2 in the first connection. - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1))); - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2))); - - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); - - // Try to move 2 to be a child of 1 from connection 2. This should fail as 2 - // should not be able to access 1. - ASSERT_FALSE(connection2_->AddView(BuildViewId(1, 1), BuildViewId(1, 2))); - - // Try to reparent 1 to the root. A connection is not allowed to reparent its - // roots. - ASSERT_FALSE(connection2_->AddView(BuildViewId(0, 1), BuildViewId(1, 1))); -} - -// Verify RemoveViewFromParent fails for views that are descendants of the -// roots. -TEST_F(ViewManagerTest, CantRemoveViewsInOtherRoots) { - // Create 1 and 2 in the first connection and parent both to the root. - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1))); - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2))); - - ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1))); - ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 2))); - - // Establish the second connection and give it the root 1. - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); - - // Connection 2 should not be able to remove view 2 or 1 from its parent. - ASSERT_FALSE(connection2_->RemoveViewFromParent(BuildViewId(1, 2))); - ASSERT_FALSE(connection2_->RemoveViewFromParent(BuildViewId(1, 1))); - - // Create views 10 and 11 in 2. - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 10))); - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 11))); - - // Parent 11 to 10. - ASSERT_TRUE(connection2_->AddView(BuildViewId(2, 10), BuildViewId(2, 11))); - // Remove 11 from 10. - ASSERT_TRUE(connection2_->RemoveViewFromParent(BuildViewId(2, 11))); - - // Verify nothing was actually removed. - { - std::vector<TestView> views; - connection_->GetViewTree(BuildViewId(0, 1), &views); - ASSERT_EQ(3u, views.size()); - EXPECT_EQ("view=0,1 parent=null", views[0].ToString()); - EXPECT_EQ("view=1,1 parent=0,1", views[1].ToString()); - EXPECT_EQ("view=1,2 parent=0,1", views[2].ToString()); - } -} - -// Verify GetViewTree fails for views that are not descendants of the roots. -TEST_F(ViewManagerTest, CantGetViewTreeOfOtherRoots) { - // Create 1 and 2 in the first connection and parent both to the root. - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1))); - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2))); - - ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1))); - ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 2))); - - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); - - std::vector<TestView> views; - - // Should get nothing for the root. - connection2_->GetViewTree(BuildViewId(0, 1), &views); - ASSERT_TRUE(views.empty()); - - // Should get nothing for view 2. - connection2_->GetViewTree(BuildViewId(1, 2), &views); - ASSERT_TRUE(views.empty()); - - // Should get view 1 if asked for. - connection2_->GetViewTree(BuildViewId(1, 1), &views); - ASSERT_EQ(1u, views.size()); - EXPECT_EQ("view=1,1 parent=null", views[0].ToString()); -} - -TEST_F(ViewManagerTest, OnViewInput) { - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1))); - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); - - // Dispatch an event to the view and verify its received. - { - EventPtr event(Event::New()); - event->action = static_cast<EventType>(1); - connection_->window_manager_client()->DispatchInputEventToView( - BuildViewId(1, 1), event.Pass()); - connection2_->DoRunLoopUntilChangesCount(1); - const Changes changes(ChangesToDescription1(connection2_->changes())); - ASSERT_EQ(1u, changes.size()); - EXPECT_EQ("InputEvent view=1,1 event_action=1", changes[0]); - } -} - -TEST_F(ViewManagerTest, EmbedWithSameViewId) { - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); - - ASSERT_NO_FATAL_FAILURE( - EstablishThirdConnection(connection_, BuildViewId(1, 1))); - - // Connection2 should have been told the view was deleted. - { - connection2_->DoRunLoopUntilChangesCount(1); - const Changes changes(ChangesToDescription1(connection2_->changes())); - ASSERT_EQ(1u, changes.size()); - EXPECT_EQ("ViewDeleted view=1,1", changes[0]); - } - - // Connection2 has no root. Verify it can't see view 1,1 anymore. - { - std::vector<TestView> views; - connection2_->GetViewTree(BuildViewId(1, 1), &views); - EXPECT_TRUE(views.empty()); - } -} - -TEST_F(ViewManagerTest, EmbedWithSameViewId2) { - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(true)); - - ASSERT_NO_FATAL_FAILURE( - EstablishThirdConnection(connection_, BuildViewId(1, 1))); - - // Connection2 should have been told the view was deleted. - connection2_->DoRunLoopUntilChangesCount(1); - connection2_->ClearChanges(); - - // Create a view in the third connection and parent it to the root. - ASSERT_TRUE(connection3_->CreateView(BuildViewId(3, 1))); - ASSERT_TRUE(connection3_->AddView(BuildViewId(1, 1), BuildViewId(3, 1))); - - // Connection 1 should have been told about the add (it owns the view). - { - connection_->DoRunLoopUntilChangesCount(1); - const Changes changes(ChangesToDescription1(connection_->changes())); - ASSERT_EQ(1u, changes.size()); - EXPECT_EQ("HierarchyChanged view=3,1 new_parent=1,1 old_parent=null", - changes[0]); - } - - // Embed 1,1 again. - { - // We should get a new connection for the new embedding. - ASSERT_TRUE(connection_->Embed(BuildViewId(1, 1), kTestServiceURL)); - ViewManagerProxy* connection4 = ViewManagerProxy::WaitForInstance(); - connection4->DoRunLoopUntilChangesCount(1); - const std::vector<Change>& changes(connection4->changes()); - ASSERT_EQ(1u, changes.size()); - EXPECT_EQ("OnEmbed creator=mojo:window_manager", - ChangesToDescription1(changes)[0]); - EXPECT_EQ("[view=1,1 parent=null]", ChangeViewDescription(changes)); - - // And 3 should get a delete. - connection3_->DoRunLoopUntilChangesCount(1); - ASSERT_EQ(1u, connection3_->changes().size()); - EXPECT_EQ("ViewDeleted view=1,1", - ChangesToDescription1(connection3_->changes())[0]); - } - - // Connection3_ has no root. Verify it can't see view 1,1 anymore. - { - std::vector<TestView> views; - connection3_->GetViewTree(BuildViewId(1, 1), &views); - EXPECT_TRUE(views.empty()); - } - - // Verify 3,1 is no longer parented to 1,1. We have to do this from 1,1 as - // connection3_ can no longer see 1,1. - { - std::vector<TestView> views; - connection_->GetViewTree(BuildViewId(1, 1), &views); - ASSERT_EQ(1u, views.size()); - EXPECT_EQ("view=1,1 parent=null", views[0].ToString()); - } - - // Verify connection3_ can still see the view it created 3,1. - { - std::vector<TestView> views; - connection3_->GetViewTree(BuildViewId(3, 1), &views); - ASSERT_EQ(1u, views.size()); - EXPECT_EQ("view=3,1 parent=null", views[0].ToString()); - } -} - -// Assertions for SetViewVisibility. -TEST_F(ViewManagerTest, SetViewVisibility) { - // Create 1 and 2 in the first connection and parent both to the root. - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1))); - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2))); - - ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1))); - { - std::vector<TestView> views; - connection_->GetViewTree(BuildViewId(0, 1), &views); - ASSERT_EQ(2u, views.size()); - EXPECT_EQ("view=0,1 parent=null visible=true drawn=true", - views[0].ToString2()); - EXPECT_EQ("view=1,1 parent=0,1 visible=false drawn=false", - views[1].ToString2()); - } - - ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 1), true)); - ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 2), true)); - { - std::vector<TestView> views; - connection_->GetViewTree(BuildViewId(0, 1), &views); - ASSERT_EQ(2u, views.size()); - EXPECT_EQ("view=0,1 parent=null visible=true drawn=true", - views[0].ToString2()); - EXPECT_EQ("view=1,1 parent=0,1 visible=true drawn=true", - views[1].ToString2()); - } - - // Hide 1. - ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 1), false)); - { - std::vector<TestView> views; - connection_->GetViewTree(BuildViewId(1, 1), &views); - ASSERT_EQ(1u, views.size()); - EXPECT_EQ("view=1,1 parent=0,1 visible=false drawn=false", - views[0].ToString2()); - } - - // Attach 2 to 1. - ASSERT_TRUE(connection_->AddView(BuildViewId(1, 1), BuildViewId(1, 2))); - { - std::vector<TestView> views; - connection_->GetViewTree(BuildViewId(1, 1), &views); - ASSERT_EQ(2u, views.size()); - EXPECT_EQ("view=1,1 parent=0,1 visible=false drawn=false", - views[0].ToString2()); - EXPECT_EQ("view=1,2 parent=1,1 visible=true drawn=false", - views[1].ToString2()); - } - - // Show 1. - ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 1), true)); - { - std::vector<TestView> views; - connection_->GetViewTree(BuildViewId(1, 1), &views); - ASSERT_EQ(2u, views.size()); - EXPECT_EQ("view=1,1 parent=0,1 visible=true drawn=true", - views[0].ToString2()); - EXPECT_EQ("view=1,2 parent=1,1 visible=true drawn=true", - views[1].ToString2()); - } -} - -// Assertions for SetViewVisibility sending notifications. -TEST_F(ViewManagerTest, SetViewVisibilityNotifications) { - // Create 1,1 and 1,2, 1,2 and child of 1,1 and 1,1 a child of the root. - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1))); - ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 1), true)); - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 2))); - ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 2), true)); - ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1))); - ASSERT_TRUE(connection_->AddView(BuildViewId(1, 1), BuildViewId(1, 2))); - - // Establish the second connection at 1,2. - ASSERT_NO_FATAL_FAILURE( - EstablishSecondConnectionWithRoot(BuildViewId(1, 2))); - - // Add 2,3 as a child of 1,2. - ASSERT_TRUE(connection2_->CreateView(BuildViewId(2, 3))); - ASSERT_TRUE(connection2_->SetViewVisibility(BuildViewId(2, 3), true)); - connection_->ClearChanges(); - ASSERT_TRUE(connection2_->AddView(BuildViewId(1, 2), BuildViewId(2, 3))); - connection_->DoRunLoopUntilChangesCount(1); - - // Hide 1,2 from connection 1. Connection 2 should see this. - ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 2), false)); - { - connection2_->DoRunLoopUntilChangesCount(1); - ASSERT_EQ(1u, connection2_->changes().size()); - EXPECT_EQ("VisibilityChanged view=1,2 visible=false", - ChangesToDescription1(connection2_->changes())[0]); - } - - // Show 1,2 from connection 2, connection 1 should be notified. - ASSERT_TRUE(connection2_->SetViewVisibility(BuildViewId(1, 2), true)); - { - connection_->DoRunLoopUntilChangesCount(1); - ASSERT_EQ(1u, connection_->changes().size()); - EXPECT_EQ("VisibilityChanged view=1,2 visible=true", - ChangesToDescription1(connection_->changes())[0]); - } - - // Hide 1,1, connection 2 should be told the draw state changed. - ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 1), false)); - { - connection2_->DoRunLoopUntilChangesCount(1); - ASSERT_EQ(1u, connection2_->changes().size()); - EXPECT_EQ("DrawnStateChanged view=1,2 drawn=false", - ChangesToDescription1(connection2_->changes())[0]); - } - - // Show 1,1 from connection 1. Connection 2 should see this. - ASSERT_TRUE(connection_->SetViewVisibility(BuildViewId(1, 1), true)); - { - connection2_->DoRunLoopUntilChangesCount(1); - ASSERT_EQ(1u, connection2_->changes().size()); - EXPECT_EQ("DrawnStateChanged view=1,2 drawn=true", - ChangesToDescription1(connection2_->changes())[0]); - } - - // Change visibility of 2,3, connection 1 should see this. - connection_->ClearChanges(); - ASSERT_TRUE(connection2_->SetViewVisibility(BuildViewId(2, 3), false)); - { - connection_->DoRunLoopUntilChangesCount(1); - ASSERT_EQ(1u, connection_->changes().size()); - EXPECT_EQ("VisibilityChanged view=2,3 visible=false", - ChangesToDescription1(connection_->changes())[0]); - } - - // Remove 1,1 from the root, connection 2 should see drawn state changed. - ASSERT_TRUE(connection_->RemoveViewFromParent(BuildViewId(1, 1))); - { - connection2_->DoRunLoopUntilChangesCount(1); - ASSERT_EQ(1u, connection2_->changes().size()); - EXPECT_EQ("DrawnStateChanged view=1,2 drawn=false", - ChangesToDescription1(connection2_->changes())[0]); - } - - // Add 1,1 back to the root, connection 2 should see drawn state changed. - ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1))); - { - connection2_->DoRunLoopUntilChangesCount(1); - ASSERT_EQ(1u, connection2_->changes().size()); - EXPECT_EQ("DrawnStateChanged view=1,2 drawn=true", - ChangesToDescription1(connection2_->changes())[0]); - } -} - -TEST_F(ViewManagerTest, SetViewProperty) { - // Create 1 and 2 in the first connection and parent both to the root. - ASSERT_TRUE(connection_->CreateView(BuildViewId(1, 1))); - - ASSERT_NO_FATAL_FAILURE(EstablishSecondConnection(false)); - - ASSERT_TRUE(connection_->AddView(BuildViewId(0, 1), BuildViewId(1, 1))); - { - std::vector<TestView> views; - connection_->GetViewTree(BuildViewId(0, 1), &views); - ASSERT_EQ(2u, views.size()); - EXPECT_EQ("view=0,1 parent=null visible=true drawn=true", - views[0].ToString2()); - EXPECT_EQ("view=1,1 parent=0,1 visible=false drawn=false", - views[1].ToString2()); - - ASSERT_EQ(0u, views[1].properties.size()); - } - - // Set properties on 1. - std::vector<uint8_t> one(1, '1'); - ASSERT_TRUE(connection_->SetViewProperty(BuildViewId(1, 1), "one", &one)); - { - connection2_->DoRunLoopUntilChangesCount(1); - ASSERT_EQ(1u, connection2_->changes().size()); - EXPECT_EQ("PropertyChanged view=1,1 key=one value=1", - ChangesToDescription1(connection2_->changes())[0]); - } - - // Test that our properties exist in the view tree - { - std::vector<TestView> views; - connection_->GetViewTree(BuildViewId(1, 1), &views); - ASSERT_EQ(1u, views.size()); - ASSERT_EQ(1u, views[0].properties.size()); - EXPECT_EQ(one, views[0].properties["one"]); - } - - // Set back to null. - ASSERT_TRUE(connection_->SetViewProperty(BuildViewId(1, 1), "one", NULL)); - { - connection2_->DoRunLoopUntilChangesCount(1); - ASSERT_EQ(1u, connection2_->changes().size()); - EXPECT_EQ("PropertyChanged view=1,1 key=one value=NULL", - ChangesToDescription1(connection2_->changes())[0]); - } -} - -// WARNING: this class is deprecated and will be replaced with -// view_manager_server_apptest soonish. Add new tests there. - -} // namespace service -} // namespace mojo