Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / mojo / services / window_manager / window_manager_api_unittest.cc
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/memory/scoped_vector.h"
7 #include "mojo/application_manager/application_manager.h"
8 #include "mojo/public/cpp/application/application_delegate.h"
9 #include "mojo/public/cpp/application/application_impl.h"
10 #include "mojo/public/cpp/application/service_provider_impl.h"
11 #include "mojo/public/interfaces/application/service_provider.mojom.h"
12 #include "mojo/services/public/cpp/view_manager/types.h"
13 #include "mojo/services/public/cpp/view_manager/view.h"
14 #include "mojo/services/public/cpp/view_manager/view_manager.h"
15 #include "mojo/services/public/cpp/view_manager/view_manager_client_factory.h"
16 #include "mojo/services/public/cpp/view_manager/view_manager_delegate.h"
17 #include "mojo/services/public/interfaces/view_manager/view_manager.mojom.h"
18 #include "mojo/services/public/interfaces/window_manager/window_manager.mojom.h"
19 #include "mojo/shell/shell_test_helper.h"
20 #include "testing/gtest/include/gtest/gtest.h"
21
22 namespace mojo {
23 namespace {
24
25 const char kTestServiceURL[] = "mojo:test_url";
26
27 void EmptyResultCallback(bool result) {}
28
29 // Callback from Embed(). |result| is the result of the Embed() call and
30 // |run_loop| the nested RunLoop.
31 void ResultCallback(bool* result_cache, base::RunLoop* run_loop, bool result) {
32   *result_cache = result;
33   run_loop->Quit();
34 }
35
36 // Responsible for establishing the initial ViewManagerService connection.
37 // Blocks until result is determined.
38 bool InitEmbed(ViewManagerInitService* view_manager_init,
39                const std::string& url) {
40   bool result = false;
41   base::RunLoop run_loop;
42   ServiceProviderPtr sp;
43   BindToProxy(new ServiceProviderImpl, &sp);
44   view_manager_init->Embed(url, sp.Pass(),
45                            base::Bind(&ResultCallback, &result, &run_loop));
46   run_loop.Run();
47   return result;
48 }
49
50 class TestWindowManagerClient : public WindowManagerClient {
51  public:
52   typedef base::Callback<void(Id, Id)>
53       TwoNodeCallback;
54
55   explicit TestWindowManagerClient(base::RunLoop* run_loop)
56       : run_loop_(run_loop) {}
57   virtual ~TestWindowManagerClient() {}
58
59   void set_focus_changed_callback(const TwoNodeCallback& callback) {
60     focus_changed_callback_ = callback;
61   }
62   void set_active_window_changed_callback(const TwoNodeCallback& callback) {
63     active_window_changed_callback_ = callback;
64   }
65
66  private:
67   // Overridden from WindowManagerClient:
68   virtual void OnWindowManagerReady() MOJO_OVERRIDE {
69     run_loop_->Quit();
70   }
71   virtual void OnCaptureChanged(
72       Id old_capture_node_id,
73       Id new_capture_node_id) MOJO_OVERRIDE {
74   }
75   virtual void OnFocusChanged(
76       Id old_focused_node_id,
77       Id new_focused_node_id) MOJO_OVERRIDE {
78     if (!focus_changed_callback_.is_null())
79       focus_changed_callback_.Run(old_focused_node_id, new_focused_node_id);
80   }
81   virtual void OnActiveWindowChanged(
82       Id old_active_window,
83       Id new_active_window) MOJO_OVERRIDE {
84     if (!active_window_changed_callback_.is_null())
85       active_window_changed_callback_.Run(old_active_window, new_active_window);
86   }
87
88   base::RunLoop* run_loop_;
89   TwoNodeCallback focus_changed_callback_;
90   TwoNodeCallback active_window_changed_callback_;
91
92   DISALLOW_COPY_AND_ASSIGN(TestWindowManagerClient);
93 };
94
95 class TestApplicationLoader : public ApplicationLoader,
96                               public ApplicationDelegate,
97                               public ViewManagerDelegate {
98  public:
99   typedef base::Callback<void(View*)> RootAddedCallback;
100
101   explicit TestApplicationLoader(const RootAddedCallback& root_added_callback)
102       : root_added_callback_(root_added_callback) {}
103   virtual ~TestApplicationLoader() {}
104
105  private:
106   // Overridden from ApplicationLoader:
107   virtual void Load(ApplicationManager* application_manager,
108                     const GURL& url,
109                     scoped_refptr<LoadCallbacks> callbacks) MOJO_OVERRIDE {
110     ScopedMessagePipeHandle shell_handle = callbacks->RegisterApplication();
111     if (!shell_handle.is_valid())
112       return;
113     scoped_ptr<ApplicationImpl> app(
114         new ApplicationImpl(this, shell_handle.Pass()));
115     apps_.push_back(app.release());
116   }
117   virtual void OnApplicationError(ApplicationManager* application_manager,
118                                   const GURL& url) MOJO_OVERRIDE {}
119
120   // Overridden from ApplicationDelegate:
121   virtual void Initialize(ApplicationImpl* app) MOJO_OVERRIDE {
122     view_manager_client_factory_.reset(
123         new ViewManagerClientFactory(app->shell(), this));
124   }
125
126   virtual bool ConfigureIncomingConnection(
127       ApplicationConnection* connection) MOJO_OVERRIDE {
128     connection->AddService(view_manager_client_factory_.get());
129     return true;
130   }
131
132   // Overridden from ViewManagerDelegate:
133   virtual void OnEmbed(
134       ViewManager* view_manager,
135       View* root,
136       ServiceProviderImpl* exported_services,
137       scoped_ptr<ServiceProvider> imported_services) MOJO_OVERRIDE {
138     root_added_callback_.Run(root);
139   }
140   virtual void OnViewManagerDisconnected(
141       ViewManager* view_manager) MOJO_OVERRIDE {
142   }
143
144   RootAddedCallback root_added_callback_;
145
146   ScopedVector<ApplicationImpl> apps_;
147   scoped_ptr<ViewManagerClientFactory> view_manager_client_factory_;
148
149   DISALLOW_COPY_AND_ASSIGN(TestApplicationLoader);
150 };
151
152 }  // namespace
153
154 class WindowManagerApiTest : public testing::Test {
155  public:
156   WindowManagerApiTest() {}
157   virtual ~WindowManagerApiTest() {}
158
159  protected:
160   typedef std::pair<Id, Id> TwoIds;
161
162   Id WaitForEmbed() {
163     Id id;
164     base::RunLoop run_loop;
165     root_added_callback_ = base::Bind(&WindowManagerApiTest::OnEmbed,
166                                       base::Unretained(this), &id, &run_loop);
167     run_loop.Run();
168     return id;
169   }
170
171   TwoIds WaitForFocusChange() {
172     TwoIds old_and_new;
173     base::RunLoop run_loop;
174     window_manager_client()->set_focus_changed_callback(
175         base::Bind(&WindowManagerApiTest::OnFocusChanged,
176                    base::Unretained(this), &old_and_new, &run_loop));
177     run_loop.Run();
178     return old_and_new;
179   }
180
181   TwoIds WaitForActiveWindowChange() {
182     TwoIds old_and_new;
183     base::RunLoop run_loop;
184     window_manager_client()->set_active_window_changed_callback(
185         base::Bind(&WindowManagerApiTest::OnActiveWindowChanged,
186                    base::Unretained(this), &old_and_new, &run_loop));
187     run_loop.Run();
188     return old_and_new;
189   }
190
191   Id OpenWindow() {
192     return OpenWindowWithURL(kTestServiceURL);
193   }
194
195   Id OpenWindowWithURL(const std::string& url) {
196     InitEmbed(view_manager_init_.get(), url);
197     return WaitForEmbed();
198   }
199
200   TestWindowManagerClient* window_manager_client() {
201     return window_manager_client_.get();
202   }
203
204   WindowManagerServicePtr window_manager_;
205
206  private:
207   // Overridden from testing::Test:
208   virtual void SetUp() MOJO_OVERRIDE {
209     test_helper_.Init();
210     test_helper_.SetLoaderForURL(
211         scoped_ptr<ApplicationLoader>(new TestApplicationLoader(base::Bind(
212             &WindowManagerApiTest::OnRootAdded, base::Unretained(this)))),
213         GURL(kTestServiceURL));
214     test_helper_.application_manager()->ConnectToService(
215         GURL("mojo:mojo_view_manager"), &view_manager_init_);
216     ASSERT_TRUE(InitEmbed(view_manager_init_.get(),
217                           "mojo:mojo_core_window_manager"));
218     ConnectToWindowManager();
219   }
220   virtual void TearDown() MOJO_OVERRIDE {}
221
222   void ConnectToWindowManager() {
223     test_helper_.application_manager()->ConnectToService(
224         GURL("mojo:mojo_core_window_manager"), &window_manager_);
225     base::RunLoop connect_loop;
226     window_manager_client_.reset(new TestWindowManagerClient(&connect_loop));
227     window_manager_.set_client(window_manager_client());
228     connect_loop.Run();
229   }
230
231   void OnRootAdded(View* root) {
232     if (!root_added_callback_.is_null())
233       root_added_callback_.Run(root);
234   }
235
236   void OnEmbed(Id* root_id,
237                base::RunLoop* loop,
238                View* root) {
239     *root_id = root->id();
240     loop->Quit();
241   }
242
243   void OnFocusChanged(TwoIds* old_and_new,
244                       base::RunLoop* run_loop,
245                       Id old_focused_node_id,
246                       Id new_focused_node_id) {
247     DCHECK(old_and_new);
248     old_and_new->first = old_focused_node_id;
249     old_and_new->second = new_focused_node_id;
250     run_loop->Quit();
251   }
252
253   void OnActiveWindowChanged(TwoIds* old_and_new,
254                              base::RunLoop* run_loop,
255                              Id old_focused_node_id,
256                              Id new_focused_node_id) {
257     DCHECK(old_and_new);
258     old_and_new->first = old_focused_node_id;
259     old_and_new->second = new_focused_node_id;
260     run_loop->Quit();
261   }
262
263   shell::ShellTestHelper test_helper_;
264   ViewManagerInitServicePtr view_manager_init_;
265   scoped_ptr<TestWindowManagerClient> window_manager_client_;
266   TestApplicationLoader::RootAddedCallback root_added_callback_;
267
268   DISALLOW_COPY_AND_ASSIGN(WindowManagerApiTest);
269 };
270
271 TEST_F(WindowManagerApiTest, FocusAndActivateWindow) {
272   Id first_window = OpenWindow();
273   window_manager_->FocusWindow(first_window,
274                                base::Bind(&EmptyResultCallback));
275   TwoIds ids = WaitForFocusChange();
276   EXPECT_TRUE(ids.first == 0);
277   EXPECT_EQ(ids.second, first_window);
278
279   Id second_window = OpenWindow();
280   window_manager_->ActivateWindow(second_window,
281                                   base::Bind(&EmptyResultCallback));
282   ids = WaitForActiveWindowChange();
283   EXPECT_EQ(ids.first, first_window);
284   EXPECT_EQ(ids.second, second_window);
285 }
286
287 }  // namespace mojo