GCC Code Coverage Report


Directory: ./
File: backends/backend_impl.cpp
Date: 2023-04-20 22:59:23
Exec Total Coverage
Lines: 53 83 63.9%
Branches: 36 74 48.6%

Line Branch Exec Source
1 /*
2 SPDX-FileCopyrightText: 2020 Roman Gilg <subdiff@gmail.com>
3
4 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only
5 */
6 #include "backend_impl.h"
7
8 #include "device.h"
9 #include "filer_controller.h"
10 #include "generator.h"
11 #include "logging.h"
12 #include "output.h"
13
14 #include <QRectF>
15
16 namespace Disman
17 {
18
19 58 BackendImpl::BackendImpl()
20 : Backend()
21 58 , m_device{new Device}
22 116 , m_filer_controller{new Filer_controller(m_device.get())}
23 {
24 58 connect(m_device.get(), &Device::lid_open_changed, this, &BackendImpl::load_lid_config);
25 58 }
26
27 114 BackendImpl::~BackendImpl() = default;
28
29 26 void BackendImpl::init([[maybe_unused]] QVariantMap const& arguments)
30 {
31 // noop, maybe overridden in individual backends.
32 26 }
33
34 161 Disman::ConfigPtr BackendImpl::config() const
35 {
36 161 m_config_initialized = true;
37
38 161 auto config = config_impl();
39
40
6/6
✓ Branch 2 taken 118 times.
✓ Branch 3 taken 43 times.
✓ Branch 5 taken 78 times.
✓ Branch 6 taken 40 times.
✓ Branch 7 taken 78 times.
✓ Branch 8 taken 83 times.
161 if (config->cause() == Config::Cause::unknown && m_config) {
41 78 config->set_cause(m_config->cause());
42 }
43
44 161 return config;
45 }
46
47 214 Disman::ConfigPtr BackendImpl::config_impl() const
48 {
49 214 auto config = std::make_shared<Config>();
50
51 // We update from the windowing system first so the controller knows about the current
52 // configuration and then update one more time so the windowing system can override values
53 // it provides itself.
54 214 update_config(config);
55 214 m_filer_controller->read(config);
56 214 update_config(config);
57
58 214 return config;
59 }
60
61 19 void BackendImpl::set_config(Disman::ConfigPtr const& config)
62 {
63
4/8
✓ Branch 1 taken 19 times.
✗ Branch 2 not taken.
✗ Branch 6 not taken.
✓ Branch 7 taken 19 times.
✓ Branch 8 taken 19 times.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✓ Branch 12 taken 19 times.
19 if (!config || config->compare(m_config)) {
64 // No change by new config. Do nothing.
65 return;
66 }
67
68
2/2
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 17 times.
19 if (!set_config_impl(config)) {
69 // No change to the system but other changes that need to be synced with other Disman
70 // clients so emit a config_changed signal directly.
71 2 m_config = config;
72 2 Q_EMIT config_changed(config);
73 }
74 }
75
76 42 bool BackendImpl::set_config_impl(Disman::ConfigPtr const& config)
77 {
78
1/2
✓ Branch 2 taken 42 times.
✗ Branch 3 not taken.
42 if (QLoggingCategory category("disman.backend"); category.isEnabled(QtDebugMsg)) {
79
2/2
✓ Branch 7 taken 42 times.
✓ Branch 8 taken 42 times.
126 qCDebug(DISMAN_BACKEND) << "About to set config."
80 84 << "\nPrevious config:" << this->config()
81 84 << "\nNew config:" << config;
82 42 }
83
84 42 m_filer_controller->write(config);
85
86
1/2
✗ Branch 3 not taken.
✓ Branch 4 taken 42 times.
42 if (config->supported_features().testFlag(Config::Feature::OutputReplication)) {
87 for (auto const& [key, output] : config->outputs()) {
88 if (auto source_id = output->replication_source()) {
89 auto source = config->output(source_id);
90 output->set_position(source->position());
91 output->force_geometry(source->geometry());
92 }
93 }
94 }
95
96 42 return set_config_system(config);
97 }
98
99 53 bool BackendImpl::handle_config_change()
100 {
101 // We need the config with its own cause, so we call config_impl here.
102 53 auto cfg = config_impl();
103
104
10/10
✓ Branch 1 taken 32 times.
✓ Branch 2 taken 21 times.
✓ Branch 8 taken 2 times.
✓ Branch 9 taken 30 times.
✓ Branch 10 taken 32 times.
✓ Branch 11 taken 21 times.
✓ Branch 13 taken 32 times.
✓ Branch 14 taken 21 times.
✓ Branch 16 taken 23 times.
✓ Branch 17 taken 30 times.
53 if (!m_config || m_config->hash() != cfg->hash()) {
105
2/2
✓ Branch 11 taken 23 times.
✓ Branch 12 taken 23 times.
46 qCDebug(DISMAN_BACKEND) << "Config with new output pattern received:" << cfg;
106
107
2/2
✓ Branch 2 taken 20 times.
✓ Branch 3 taken 3 times.
23 if (cfg->cause() == Config::Cause::unknown) {
108
2/2
✓ Branch 6 taken 20 times.
✓ Branch 7 taken 20 times.
40 qCDebug(DISMAN_BACKEND)
109 20 << "Config received that is unknown. Creating an optimized config now.";
110 20 Generator generator(cfg);
111 20 generator.optimize();
112 20 cfg = generator.config();
113 20 } else {
114 // We set the windowing system to our saved values. They were overriden before so
115 // re-read them.
116 3 m_filer_controller->read(cfg);
117 }
118
119 23 m_config = cfg;
120
121
2/2
✓ Branch 1 taken 20 times.
✓ Branch 2 taken 3 times.
23 if (set_config_impl(cfg)) {
122
2/2
✓ Branch 7 taken 20 times.
✓ Branch 8 taken 20 times.
40 qCDebug(DISMAN_BACKEND) << "Config for new output pattern sent.";
123 20 return false;
124 }
125 }
126
127 33 Q_EMIT config_changed(cfg);
128 33 return true;
129 53 }
130
131 void BackendImpl::load_lid_config()
132 {
133 if (!m_config_initialized) {
134 qCWarning(DISMAN_BACKEND) << "Lid open state changed but first config has not yet been "
135 "initialized. Doing nothing.";
136 return;
137 }
138
139 auto cfg = config();
140 if (cfg->outputs().size() == 1) {
141 // Open-lid configuration is only relevant with more than one output.
142 return;
143 }
144
145 if (m_device->lid_open()) {
146 // The lid has been opnened. Try to load the open-lid file.
147 if (!m_filer_controller->load_lid_file(cfg)) {
148 qCWarning(DISMAN_BACKEND)
149 << "Loading open-lid file failed. Generating an optimal config instead.";
150 return;
151 }
152 qCDebug(DISMAN_BACKEND) << "Loaded lid-open file on lid being opened.";
153 } else {
154 // The lid has been closed, we write the current config as open-lid-config and then generate
155 // an optimized one with the embedded display disabled that gets applied.
156 Generator generator(cfg);
157 qCDebug(DISMAN_BACKEND) << "Lid closed, trying to disable embedded display.";
158
159 if (!generator.disable_embedded()) {
160 // Alternative config could not be generated.
161 qCWarning(DISMAN_BACKEND) << "Embedded display could not be disabled.";
162 return;
163 }
164 if (!m_filer_controller->save_lid_file(cfg)) {
165 qCWarning(DISMAN_BACKEND) << "Failed to save open-lid file.";
166 return;
167 }
168 cfg = generator.config();
169 }
170
171 set_config_impl(cfg);
172 }
173
174 }
175