| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "base/bind.h" | |
| 6 #include "base/command_line.h" | |
| 7 #include "base/memory/scoped_vector.h" | |
| 8 #include "mojo/application_manager/application_manager.h" | |
| 9 #include "mojo/public/cpp/application/application_delegate.h" | |
| 10 #include "mojo/public/cpp/application/application_impl.h" | |
| 11 #include "mojo/public/cpp/application/service_provider_impl.h" | |
| 12 #include "mojo/public/interfaces/application/service_provider.mojom.h" | |
| 13 #include "mojo/services/public/cpp/view_manager/types.h" | |
| 14 #include "mojo/services/public/cpp/view_manager/view.h" | |
| 15 #include "mojo/services/public/cpp/view_manager/view_manager.h" | |
| 16 #include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h" | |
| 17 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h" | |
| 18 #include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h" | |
| 19 #include "mojo/services/public/interfaces/window_manager/window_manager.mojom.h" | |
| 20 #include "mojo/shell/shell_test_helper.h" | |
| 21 #include "testing/gtest/include/gtest/gtest.h" | |
| 22 | |
| 23 namespace mojo { | |
| 24 namespace { | |
| 25 | |
| 26 const char kTestServiceURL[] = "mojo:test_url"; | |
| 27 | |
| 28 void EmptyResultCallback(bool result) {} | |
| 29 | |
| 30 class TestWindowManagerClient : public WindowManagerClient { | |
| 31 public: | |
| 32 typedef base::Callback<void(Id, Id)> | |
| 33 TwoNodeCallback; | |
| 34 | |
| 35 explicit TestWindowManagerClient(base::RunLoop* run_loop) | |
| 36 : run_loop_(run_loop) {} | |
| 37 ~TestWindowManagerClient() override {} | |
| 38 | |
| 39 void set_focus_changed_callback(const TwoNodeCallback& callback) { | |
| 40 focus_changed_callback_ = callback; | |
| 41 } | |
| 42 void set_active_window_changed_callback(const TwoNodeCallback& callback) { | |
| 43 active_window_changed_callback_ = callback; | |
| 44 } | |
| 45 | |
| 46 private: | |
| 47 // Overridden from WindowManagerClient: | |
| 48 void OnCaptureChanged(Id old_capture_node_id, | |
| 49 Id new_capture_node_id) override {} | |
| 50 void OnFocusChanged(Id old_focused_node_id, Id new_focused_node_id) override { | |
| 51 if (!focus_changed_callback_.is_null()) | |
| 52 focus_changed_callback_.Run(old_focused_node_id, new_focused_node_id); | |
| 53 } | |
| 54 void OnActiveWindowChanged(Id old_active_window, | |
| 55 Id new_active_window) override { | |
| 56 if (!active_window_changed_callback_.is_null()) | |
| 57 active_window_changed_callback_.Run(old_active_window, new_active_window); | |
| 58 } | |
| 59 | |
| 60 base::RunLoop* run_loop_; | |
| 61 TwoNodeCallback focus_changed_callback_; | |
| 62 TwoNodeCallback active_window_changed_callback_; | |
| 63 | |
| 64 DISALLOW_COPY_AND_ASSIGN(TestWindowManagerClient); | |
| 65 }; | |
| 66 | |
| 67 class TestApplicationLoader : public ApplicationLoader, | |
| 68 public ApplicationDelegate, | |
| 69 public ViewManagerDelegate { | |
| 70 public: | |
| 71 typedef base::Callback<void(View*)> RootAddedCallback; | |
| 72 | |
| 73 explicit TestApplicationLoader(const RootAddedCallback& root_added_callback) | |
| 74 : root_added_callback_(root_added_callback) {} | |
| 75 ~TestApplicationLoader() override {} | |
| 76 | |
| 77 private: | |
| 78 // Overridden from ApplicationLoader: | |
| 79 void Load(ApplicationManager* application_manager, | |
| 80 const GURL& url, | |
| 81 ScopedMessagePipeHandle shell_handle, | |
| 82 LoadCallback callback) override { | |
| 83 ASSERT_TRUE(shell_handle.is_valid()); | |
| 84 scoped_ptr<ApplicationImpl> app( | |
| 85 new ApplicationImpl(this, shell_handle.Pass())); | |
| 86 apps_.push_back(app.release()); | |
| 87 } | |
| 88 void OnApplicationError(ApplicationManager* application_manager, | |
| 89 const GURL& url) override {} | |
| 90 | |
| 91 // Overridden from ApplicationDelegate: | |
| 92 void Initialize(ApplicationImpl* app) override { | |
| 93 view_manager_client_factory_.reset( | |
| 94 new ViewManagerClientFactory(app->shell(), this)); | |
| 95 } | |
| 96 | |
| 97 bool ConfigureIncomingConnection(ApplicationConnection* connection) override { | |
| 98 connection->AddService(view_manager_client_factory_.get()); | |
| 99 return true; | |
| 100 } | |
| 101 | |
| 102 // Overridden from ViewManagerDelegate: | |
| 103 void OnEmbed(ViewManager* view_manager, | |
| 104 View* root, | |
| 105 ServiceProviderImpl* exported_services, | |
| 106 scoped_ptr<ServiceProvider> imported_services) override { | |
| 107 root_added_callback_.Run(root); | |
| 108 } | |
| 109 void OnViewManagerDisconnected(ViewManager* view_manager) override {} | |
| 110 | |
| 111 RootAddedCallback root_added_callback_; | |
| 112 | |
| 113 ScopedVector<ApplicationImpl> apps_; | |
| 114 scoped_ptr<ViewManagerClientFactory> view_manager_client_factory_; | |
| 115 | |
| 116 DISALLOW_COPY_AND_ASSIGN(TestApplicationLoader); | |
| 117 }; | |
| 118 | |
| 119 } // namespace | |
| 120 | |
| 121 class WindowManagerApiTest : public testing::Test { | |
| 122 public: | |
| 123 WindowManagerApiTest() {} | |
| 124 ~WindowManagerApiTest() override {} | |
| 125 | |
| 126 protected: | |
| 127 typedef std::pair<Id, Id> TwoIds; | |
| 128 | |
| 129 Id WaitForEmbed() { | |
| 130 Id id; | |
| 131 base::RunLoop run_loop; | |
| 132 root_added_callback_ = base::Bind(&WindowManagerApiTest::OnEmbed, | |
| 133 base::Unretained(this), &id, &run_loop); | |
| 134 run_loop.Run(); | |
| 135 return id; | |
| 136 } | |
| 137 | |
| 138 TwoIds WaitForFocusChange() { | |
| 139 TwoIds old_and_new; | |
| 140 base::RunLoop run_loop; | |
| 141 window_manager_client()->set_focus_changed_callback( | |
| 142 base::Bind(&WindowManagerApiTest::OnFocusChanged, | |
| 143 base::Unretained(this), &old_and_new, &run_loop)); | |
| 144 run_loop.Run(); | |
| 145 return old_and_new; | |
| 146 } | |
| 147 | |
| 148 TwoIds WaitForActiveWindowChange() { | |
| 149 TwoIds old_and_new; | |
| 150 base::RunLoop run_loop; | |
| 151 window_manager_client()->set_active_window_changed_callback( | |
| 152 base::Bind(&WindowManagerApiTest::OnActiveWindowChanged, | |
| 153 base::Unretained(this), &old_and_new, &run_loop)); | |
| 154 run_loop.Run(); | |
| 155 return old_and_new; | |
| 156 } | |
| 157 | |
| 158 Id OpenWindow() { | |
| 159 return OpenWindowWithURL(kTestServiceURL); | |
| 160 } | |
| 161 | |
| 162 Id OpenWindowWithURL(const std::string& url) { | |
| 163 base::RunLoop run_loop; | |
| 164 ServiceProviderPtr sp; | |
| 165 BindToProxy(new ServiceProviderImpl, &sp); | |
| 166 window_manager_->Embed( | |
| 167 url, MakeRequest<ServiceProvider>(sp.PassMessagePipe())); | |
| 168 run_loop.Run(); | |
| 169 return WaitForEmbed(); | |
| 170 } | |
| 171 | |
| 172 TestWindowManagerClient* window_manager_client() { | |
| 173 return window_manager_client_.get(); | |
| 174 } | |
| 175 | |
| 176 WindowManagerPtr window_manager_; | |
| 177 | |
| 178 private: | |
| 179 // Overridden from testing::Test: | |
| 180 void SetUp() override { | |
| 181 test_helper_.reset(new shell::ShellTestHelper); | |
| 182 test_helper_->Init(); | |
| 183 test_helper_->AddCustomMapping(GURL("mojo:window_manager"), | |
| 184 GURL("mojo:core_window_manager")); | |
| 185 test_helper_->SetLoaderForURL( | |
| 186 scoped_ptr<ApplicationLoader>(new TestApplicationLoader(base::Bind( | |
| 187 &WindowManagerApiTest::OnRootAdded, base::Unretained(this)))), | |
| 188 GURL(kTestServiceURL)); | |
| 189 ConnectToWindowManager2(); | |
| 190 } | |
| 191 void TearDown() override {} | |
| 192 | |
| 193 void ConnectToWindowManager2() { | |
| 194 test_helper_->application_manager()->ConnectToService( | |
| 195 GURL("mojo:window_manager"), &window_manager_); | |
| 196 base::RunLoop connect_loop; | |
| 197 window_manager_client_.reset(new TestWindowManagerClient(&connect_loop)); | |
| 198 window_manager_.set_client(window_manager_client()); | |
| 199 connect_loop.Run(); | |
| 200 | |
| 201 // The RunLoop above ensures the connection to the windowmanager completes. | |
| 202 // Without this the ApplicationManager would loads the windowmanager twice. | |
| 203 test_helper_->application_manager()->ConnectToService( | |
| 204 GURL("mojo:core_window_manager"), &window_manager_); | |
| 205 } | |
| 206 | |
| 207 void OnRootAdded(View* root) { | |
| 208 if (!root_added_callback_.is_null()) | |
| 209 root_added_callback_.Run(root); | |
| 210 } | |
| 211 | |
| 212 void OnEmbed(Id* root_id, | |
| 213 base::RunLoop* loop, | |
| 214 View* root) { | |
| 215 *root_id = root->id(); | |
| 216 loop->Quit(); | |
| 217 } | |
| 218 | |
| 219 void OnFocusChanged(TwoIds* old_and_new, | |
| 220 base::RunLoop* run_loop, | |
| 221 Id old_focused_node_id, | |
| 222 Id new_focused_node_id) { | |
| 223 DCHECK(old_and_new); | |
| 224 old_and_new->first = old_focused_node_id; | |
| 225 old_and_new->second = new_focused_node_id; | |
| 226 run_loop->Quit(); | |
| 227 } | |
| 228 | |
| 229 void OnActiveWindowChanged(TwoIds* old_and_new, | |
| 230 base::RunLoop* run_loop, | |
| 231 Id old_focused_node_id, | |
| 232 Id new_focused_node_id) { | |
| 233 DCHECK(old_and_new); | |
| 234 old_and_new->first = old_focused_node_id; | |
| 235 old_and_new->second = new_focused_node_id; | |
| 236 run_loop->Quit(); | |
| 237 } | |
| 238 | |
| 239 scoped_ptr<shell::ShellTestHelper> test_helper_; | |
| 240 scoped_ptr<TestWindowManagerClient> window_manager_client_; | |
| 241 TestApplicationLoader::RootAddedCallback root_added_callback_; | |
| 242 | |
| 243 DISALLOW_COPY_AND_ASSIGN(WindowManagerApiTest); | |
| 244 }; | |
| 245 | |
| 246 // TODO(sky): resolve this. Temporarily disabled as ApplicationManager ends up | |
| 247 // loading windowmanager twice because of the mapping of window_manager to | |
| 248 // core_window_manager. | |
| 249 TEST_F(WindowManagerApiTest, DISABLED_FocusAndActivateWindow) { | |
| 250 Id first_window = OpenWindow(); | |
| 251 window_manager_->FocusWindow(first_window, base::Bind(&EmptyResultCallback)); | |
| 252 TwoIds ids = WaitForFocusChange(); | |
| 253 EXPECT_TRUE(ids.first == 0); | |
| 254 EXPECT_EQ(ids.second, first_window); | |
| 255 | |
| 256 Id second_window = OpenWindow(); | |
| 257 window_manager_->ActivateWindow(second_window, | |
| 258 base::Bind(&EmptyResultCallback)); | |
| 259 ids = WaitForActiveWindowChange(); | |
| 260 EXPECT_EQ(ids.first, first_window); | |
| 261 EXPECT_EQ(ids.second, second_window); | |
| 262 } | |
| 263 | |
| 264 } // namespace mojo | |
| OLD | NEW |