~mir-team/mir/development-branch

« back to all changes in this revision

Viewing changes to tests/unit-tests/graphics/android/test_display_hotplug.cpp

merge trunk and resolve conflicts

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2015 Canonical Ltd.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify
 
5
 * it under the terms of the GNU General Public License version 3 as
 
6
 * published by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope that it will be useful,
 
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
 * GNU General Public License for more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License
 
14
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
15
 *
 
16
 * Authored by: Kevin DuBois <kevin.dubois@canonical.com>
 
17
 */
 
18
 
 
19
#include "src/platforms/android/server/display.h"
 
20
#include "src/platforms/android/server/hal_component_factory.h"
 
21
#include "src/server/graphics/program_factory.h"
 
22
#include "src/server/report/null_report_factory.h"
 
23
#include "mir/glib_main_loop.h"
 
24
#include "mir/time/steady_clock.h"
 
25
#include "mir_test_doubles/mock_display_device.h"
 
26
#include "mir_test_doubles/mock_framebuffer_bundle.h"
 
27
#include "mir_test_doubles/stub_gl_config.h"
 
28
#include "mir_test_doubles/mock_egl.h"
 
29
#include "mir_test_doubles/mock_gl.h"
 
30
#include "mir_test/auto_unblock_thread.h"
 
31
#include <gtest/gtest.h>
 
32
 
 
33
namespace mga=mir::graphics::android;
 
34
namespace mg=mir::graphics;
 
35
namespace geom=mir::geometry;
 
36
namespace mtd=mir::test::doubles;
 
37
 
 
38
//doesn't use the HW modules, rather tests mainloop integration
 
39
struct DisplayHotplug : ::testing::Test
 
40
{
 
41
    struct StubHwcConfig : public mga::HwcConfiguration
 
42
    {
 
43
        void power_mode(mga::DisplayName, MirPowerMode) override {}
 
44
        mga::DisplayAttribs active_attribs_for(mga::DisplayName) override
 
45
        {
 
46
            return mga::DisplayAttribs{{0,0}, {0,0}, 0.0, true, mir_pixel_format_abgr_8888, 2};
 
47
        } 
 
48
        mga::ConfigChangeSubscription subscribe_to_config_changes(
 
49
            std::function<void()> const& cb) override
 
50
        {
 
51
            hotplug_fn = cb;
 
52
            return {};
 
53
        }
 
54
        void simulate_hotplug()
 
55
        {
 
56
            hotplug_fn();
 
57
        }
 
58
        std::function<void()> hotplug_fn{[]{}};
 
59
    };
 
60
 
 
61
    struct WrappingConfig : public mga::HwcConfiguration
 
62
    {
 
63
        WrappingConfig(mga::HwcConfiguration& config) : wrapped(config) {}
 
64
 
 
65
        void power_mode(mga::DisplayName d, MirPowerMode m) override
 
66
        {
 
67
            wrapped.power_mode(d, m);
 
68
        }
 
69
        mga::DisplayAttribs active_attribs_for(mga::DisplayName d) override
 
70
        {
 
71
            return wrapped.active_attribs_for(d);
 
72
        } 
 
73
        mga::ConfigChangeSubscription subscribe_to_config_changes(
 
74
            std::function<void()> const& cb) override
 
75
        {
 
76
            return wrapped.subscribe_to_config_changes(cb);
 
77
        }
 
78
        mga::HwcConfiguration& wrapped;
 
79
    };
 
80
 
 
81
    struct StubOutputBuilder : public mga::DisplayComponentFactory
 
82
    {
 
83
        std::unique_ptr<mga::FramebufferBundle> create_framebuffers(mga::DisplayAttribs const&) override
 
84
        {
 
85
            return std::unique_ptr<mga::FramebufferBundle>(new testing::NiceMock<mtd::MockFBBundle>());
 
86
        }
 
87
 
 
88
        std::unique_ptr<mga::DisplayDevice> create_display_device() override
 
89
        {
 
90
            return std::unique_ptr<mga::DisplayDevice>(new testing::NiceMock<mtd::MockDisplayDevice>());
 
91
        }
 
92
 
 
93
        std::unique_ptr<mga::HwcConfiguration> create_hwc_configuration() override
 
94
        {
 
95
            return std::unique_ptr<mga::HwcConfiguration>(new WrappingConfig(stub_config));
 
96
        }
 
97
        StubHwcConfig stub_config;
 
98
    };
 
99
 
 
100
    testing::NiceMock<mtd::MockEGL> mock_egl;
 
101
    testing::NiceMock<mtd::MockGL> mock_gl;
 
102
    mir::GLibMainLoop mainloop{std::make_shared<mir::time::SteadyClock>()};
 
103
    mir::test::AutoUnblockThread loop{
 
104
            [this]{ mainloop.enqueue(this, [this] { mainloop.stop(); }); },
 
105
            [this]{ mainloop.run(); }};
 
106
    std::shared_ptr<StubOutputBuilder> stub_output_builder{std::make_shared<StubOutputBuilder>()};
 
107
    mga::Display display{
 
108
        stub_output_builder,
 
109
        std::make_shared<mg::ProgramFactory>(),
 
110
        std::make_shared<mtd::StubGLConfig>(),
 
111
        mir::report::null_display_report(),
 
112
        mga::OverlayOptimization::enabled};
 
113
};
 
114
 
 
115
TEST_F(DisplayHotplug, hotplug_generates_mainloop_event)
 
116
{
 
117
    std::mutex mutex;
 
118
    std::condition_variable cv;
 
119
    int call_count{0};
 
120
    std::function<void()> change_handler{[&]
 
121
    {
 
122
        std::unique_lock<decltype(mutex)> lk(mutex);
 
123
        call_count++;
 
124
        cv.notify_all();
 
125
    }};
 
126
    std::unique_lock<decltype(mutex)> lk(mutex);
 
127
    display.register_configuration_change_handler(mainloop, change_handler);
 
128
    stub_output_builder->stub_config.simulate_hotplug();
 
129
    EXPECT_TRUE(cv.wait_for(lk, std::chrono::seconds(2), [&]{ return call_count == 1; }));
 
130
 
 
131
    stub_output_builder->stub_config.simulate_hotplug();
 
132
    EXPECT_TRUE(cv.wait_for(lk, std::chrono::seconds(2), [&]{ return call_count == 2; }));
 
133
    mainloop.unregister_fd_handler(&display);
 
134
}