Index: mojo/services/view_manager/view_manager_unittest.cc |
diff --git a/mojo/services/view_manager/view_manager_unittest.cc b/mojo/services/view_manager/view_manager_unittest.cc |
deleted file mode 100644 |
index c573cf160e221b4f0f9fb0fef47018318fd1f6ce..0000000000000000000000000000000000000000 |
--- a/mojo/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/services/view_manager/ids.h" |
-#include "mojo/services/view_manager/test_change_tracker.h" |
-#include "mojo/shell/shell_test_helper.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 |