TYPE3
[iec.git] / src / type3_AndroidCloud / anbox-master / tests / anbox / graphics / layer_composer_tests.cpp
diff --git a/src/type3_AndroidCloud/anbox-master/tests/anbox/graphics/layer_composer_tests.cpp b/src/type3_AndroidCloud/anbox-master/tests/anbox/graphics/layer_composer_tests.cpp
new file mode 100644 (file)
index 0000000..846f7aa
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * Copyright (C) 2016 Simon Fels <morphis@gravedo.de>
+ *
+ * This program is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 3, as published
+ * by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranties of
+ * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
+ * PURPOSE.  See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+// Both includes need to go first as otherwise they can conflict with EGL.h
+// being included by the following includes.
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include "anbox/application/database.h"
+#include "anbox/platform/base_platform.h"
+#include "anbox/wm/multi_window_manager.h"
+#include "anbox/wm/window_state.h"
+
+#include "anbox/graphics/layer_composer.h"
+#include "anbox/graphics/multi_window_composer_strategy.h"
+
+using namespace ::testing;
+
+namespace {
+class MockRenderer : public anbox::graphics::Renderer {
+ public:
+  MOCK_METHOD3(draw, bool(EGLNativeWindowType, const anbox::graphics::Rect&,
+                          const RenderableList&));
+};
+}
+
+namespace anbox {
+namespace graphics {
+TEST(LayerComposer, FindsNoSuitableWindowForLayer) {
+  auto renderer = std::make_shared<MockRenderer>();
+
+  platform::Configuration config;
+  // The default policy will create a dumb window instance when requested
+  // from the manager.
+  auto platform = platform::create(std::string(), nullptr, config);
+  auto app_db = std::make_shared<application::Database>();
+  auto wm = std::make_shared<wm::MultiWindowManager>(platform, nullptr, app_db);
+
+  auto single_window = wm::WindowState{
+      wm::Display::Id{1},
+      true,
+      graphics::Rect{0, 0, 1024, 768},
+      "org.anbox.test.1",
+      wm::Task::Id{1},
+      wm::Stack::Id::Freeform,
+  };
+
+  wm->apply_window_state_update({single_window}, {});
+
+  LayerComposer composer(renderer, std::make_shared<MultiWindowComposerStrategy>(wm));
+
+  // A single renderable which has a different task id then the window we know
+  // about
+  RenderableList renderables = {
+      {"org.anbox.surface.2", 0, 1.0f, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
+  };
+
+  // The renderer should not be called for a layer which doesn't exist
+  EXPECT_CALL(*renderer, draw(_, _, _)).Times(0);
+
+  composer.submit_layers(renderables);
+}
+
+TEST(LayerComposer, MapsLayersToWindows) {
+  auto renderer = std::make_shared<MockRenderer>();
+
+  platform::Configuration config;
+  // The default policy will create a dumb window instance when requested
+  // from the manager.
+  auto platform = platform::create(std::string(), nullptr, config);
+  auto app_db = std::make_shared<application::Database>();
+  auto wm = std::make_shared<wm::MultiWindowManager>(platform, nullptr, app_db);
+
+  auto first_window = wm::WindowState{
+      wm::Display::Id{1},
+      true,
+      graphics::Rect{0, 0, 1024, 768},
+      "org.anbox.foo",
+      wm::Task::Id{1},
+      wm::Stack::Id::Freeform,
+  };
+
+  auto second_window = wm::WindowState{
+      wm::Display::Id{1},
+      true,
+      graphics::Rect{300, 400, 1324, 1168},
+      "org.anbox.bar",
+      wm::Task::Id{2},
+      wm::Stack::Id::Freeform,
+  };
+
+  wm->apply_window_state_update({first_window, second_window}, {});
+
+  LayerComposer composer(renderer, std::make_shared<MultiWindowComposerStrategy>(wm));
+
+  // A single renderable which has a different task id then the window we know
+  // about
+  RenderableList renderables = {
+      {"org.anbox.surface.1", 0, 1.0f, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
+      {"org.anbox.surface.2", 1, 1.0f, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
+  };
+
+  RenderableList first_window_renderables{
+      {"org.anbox.surface.1", 0, 1.0f, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
+  };
+
+  RenderableList second_window_renderables{
+      {"org.anbox.surface.2", 1, 1.0f, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
+  };
+
+  EXPECT_CALL(*renderer, draw(_, Rect{0, 0, first_window.frame().width(),
+                                      first_window.frame().height()},
+                              first_window_renderables))
+      .Times(1)
+      .WillOnce(Return(true));
+  EXPECT_CALL(*renderer, draw(_, Rect{0, 0, second_window.frame().width(),
+                                      second_window.frame().height()},
+                              second_window_renderables))
+      .Times(1)
+      .WillOnce(Return(true));
+
+  composer.submit_layers(renderables);
+}
+
+TEST(LayerComposer, WindowPartiallyOffscreen) {
+  auto renderer = std::make_shared<MockRenderer>();
+
+  platform::Configuration config;
+  // The default policy will create a dumb window instance when requested
+  // from the manager.
+  auto platform = platform::create(std::string(), nullptr, config);
+  auto app_db = std::make_shared<application::Database>();
+  auto wm = std::make_shared<wm::MultiWindowManager>(platform, nullptr, app_db);
+
+  auto window = wm::WindowState{
+      wm::Display::Id{1},
+      true,
+      graphics::Rect{-100, -100, 924, 668},
+      "org.anbox.foo",
+      wm::Task::Id{1},
+      wm::Stack::Id::Freeform,
+  };
+
+  wm->apply_window_state_update({window}, {});
+
+  LayerComposer composer(renderer, std::make_shared<MultiWindowComposerStrategy>(wm));
+
+  // Window is build out of two layers where one is placed inside the other
+  // but the layer covering the whole window is placed with its top left
+  // origin outside of the visible display area.
+  RenderableList renderables = {
+    {"org.anbox.surface.1", 0, 1.0f, {-100, -100, 924, 668}, {0, 0, 1024, 768}},
+    {"org.anbox.surface.1", 1, 1.0f, {0, 0, 100, 200}, {0, 0, 100, 200}},
+  };
+
+  RenderableList expected_renderables{
+    {"org.anbox.surface.1", 0, 1.0f, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
+    {"org.anbox.surface.1", 1, 1.0f, {100, 100, 200, 300}, {0, 0, 100, 200}},
+  };
+
+  EXPECT_CALL(*renderer, draw(_, Rect{0, 0,
+                                      window.frame().width(),
+                                      window.frame().height()},
+                              expected_renderables))
+      .Times(1)
+      .WillOnce(Return(true));
+
+  composer.submit_layers(renderables);
+}
+
+TEST(LayerComposer, PopupShouldNotCauseWindowLayerOffset) {
+  auto renderer = std::make_shared<MockRenderer>();
+
+  platform::Configuration config;
+  // The default policy will create a dumb window instance when requested
+  // from the manager.
+  auto platform = platform::create(std::string(), nullptr, config);
+  auto app_db = std::make_shared<application::Database>();
+  auto wm = std::make_shared<wm::MultiWindowManager>(platform, nullptr, app_db);
+
+  auto window = wm::WindowState{
+      wm::Display::Id{1},
+      true,
+      graphics::Rect{1120, 270, 2144, 1038},
+      "org.anbox.foo",
+      wm::Task::Id{3},
+      wm::Stack::Id::Freeform,
+  };
+
+  wm->apply_window_state_update({window}, {});
+
+  LayerComposer composer(renderer, std::make_shared<MultiWindowComposerStrategy>(wm));
+
+  // Having two renderables where the second smaller one overlaps the bigger
+  // one and goes a bit offscreen. This should be still placed correctly and
+  // the small layer should go offscreen as it is supposed to. This typically
+  // happens when a popup window appears which has a shadow attached which goes
+  // out of the window area. In our case this is not possible as the area the
+  // window has available is static.
+  RenderableList renderables = {
+    {"org.anbox.surface.3", 0, 1.0f, {1120,270,2144,1038}, {0, 0, 1024, 768}},
+    {"org.anbox.surface.3", 1, 1.0f, {1904, 246, 2164, 406}, {0, 0, 260, 160}},
+  };
+
+  RenderableList expected_renderables{
+    {"org.anbox.surface.3", 0, 1.0f, {0, 0, 1024, 768}, {0, 0, 1024, 768}},
+    {"org.anbox.surface.3", 1, 1.0f, {784, -24, 1044, 136}, {0, 0, 260, 160}},
+  };
+
+  EXPECT_CALL(*renderer, draw(_, Rect{0, 0,
+                                      window.frame().width(),
+                                      window.frame().height()},
+                              expected_renderables))
+      .Times(1)
+      .WillOnce(Return(true));
+
+  composer.submit_layers(renderables);
+}
+
+}  // namespace graphics
+}  // namespace anbox