~vanvugt/mir/mir-display-config-header

« back to all changes in this revision

Viewing changes to src/server/report/reports.cpp

  • Committer: Tarmac
  • Author(s): Christopher James Halse Rogers
  • Date: 2016-11-15 23:48:01 UTC
  • mfrom: (3730.3.26 reports-as-observers)
  • Revision ID: tarmac-20161115234801-2w603k4v3ffhfl3u
Replace the mir::Server-overridable Reports with Observers.

This resolves two problems:
1) It ensures that Mir will respect the various reporting options we provide, even when the shell wants to hook into some of the reports, and
2) It matches the semantic expectations around Reports vs Observers that (most of) the Mir team have. A couple of report call-sites which are unsafe for Observers are fixed in this branch.

Approved by mir-ci-bot, Kevin DuBois, Andreas Pokorny, Cemil Azizoglu.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2016 Canonical Ltd.
 
3
 *
 
4
 * This program is free software: you can redistribute it and/or modify it
 
5
 * under the terms of the GNU General Public License version 3,
 
6
 * as 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: Christopher James Halse Rogers <christopher.halse.rogers@canonical.com>
 
17
 */
 
18
 
 
19
#include "reports.h"
 
20
 
 
21
#include "mir/default_server_configuration.h"
 
22
#include "mir/options/option.h"
 
23
#include "logging/display_configuration_report.h"
 
24
#include "mir/observer_multiplexer.h"
 
25
#include "mir/options/configuration.h"
 
26
#include "mir/abnormal_exit.h"
 
27
 
 
28
#include "report_factory.h"
 
29
#include "lttng_report_factory.h"
 
30
#include "logging_report_factory.h"
 
31
#include "null_report_factory.h"
 
32
 
 
33
#include <string>
 
34
 
 
35
namespace mo = mir::options;
 
36
namespace mr = mir::report;
 
37
 
 
38
namespace
 
39
{
 
40
enum class ReportOutput
 
41
{
 
42
    Discarded,
 
43
    Log,
 
44
    LTTNG
 
45
};
 
46
 
 
47
std::unique_ptr<mr::ReportFactory> factory_for_type(
 
48
    mir::DefaultServerConfiguration& config,
 
49
    ReportOutput type)
 
50
{
 
51
    switch (type)
 
52
    {
 
53
    case ReportOutput::Discarded:
 
54
        return std::make_unique<mr::NullReportFactory>();
 
55
    case ReportOutput::Log:
 
56
        return std::make_unique<mr::LoggingReportFactory>(config.the_logger(), config.the_clock());
 
57
    case ReportOutput::LTTNG:
 
58
        return std::make_unique<mr::LttngReportFactory>();
 
59
    }
 
60
#ifndef __clang__
 
61
    /*
 
62
     * Clang understands that the above switch is exhaustive, so only throw here to satisfy g++'s
 
63
     * control-reaches-end-of-non-void-function diagnostic.
 
64
     *
 
65
     * This way if the above switch *becomes* non-exhaustive clang will fail to build for us.
 
66
     */
 
67
 
 
68
    using namespace std::string_literals;
 
69
    throw std::logic_error{"Requested unknown ReportOutput type:"s + std::to_string(static_cast<int>(type))};
 
70
#endif
 
71
}
 
72
 
 
73
ReportOutput parse_report_option(std::string const& opt)
 
74
{
 
75
    if (opt == mo::log_opt_value)
 
76
    {
 
77
        return ReportOutput::Log;
 
78
    }
 
79
    else if (opt == mo::lttng_opt_value)
 
80
    {
 
81
        return ReportOutput::LTTNG;
 
82
    }
 
83
    else if (opt == mo::off_opt_value)
 
84
    {
 
85
        return ReportOutput::Discarded;
 
86
    }
 
87
    else
 
88
    {
 
89
        throw mir::AbnormalExit(
 
90
            std::string("Invalid report option: ") + opt + " (valid options are: \"" +
 
91
            mo::off_opt_value + "\" and \"" + mo::log_opt_value +
 
92
            "\" and \"" + mo::lttng_opt_value + "\")");
 
93
    }
 
94
}
 
95
 
 
96
std::shared_ptr<mir::input::SeatObserver> create_seat_reports(
 
97
    mir::DefaultServerConfiguration& config,
 
98
    std::string const& opt)
 
99
{
 
100
    using namespace std::string_literals;
 
101
    try
 
102
    {
 
103
        return factory_for_type(config, parse_report_option(opt))->create_seat_report();
 
104
    }
 
105
    catch (...)
 
106
    {
 
107
        std::throw_with_nested(mir::AbnormalExit("Failed to create report for "s + mo::seat_report_opt));
 
108
    }
 
109
}
 
110
 
 
111
std::shared_ptr<mir::frontend::SessionMediatorObserver> create_session_mediator_reports(
 
112
    mir::DefaultServerConfiguration& config,
 
113
    std::string const& opt)
 
114
{
 
115
    using namespace std::string_literals;
 
116
    try
 
117
    {
 
118
        return factory_for_type(config, parse_report_option(opt))->create_session_mediator_report();
 
119
    }
 
120
    catch (...)
 
121
    {
 
122
        std::throw_with_nested(mir::AbnormalExit("Failed to create report for "s + mo::session_mediator_report_opt));
 
123
    }
 
124
}
 
125
}
 
126
 
 
127
mir::report::Reports::Reports(
 
128
    DefaultServerConfiguration& server,
 
129
    options::Option const& options)
 
130
    : display_configuration_report{std::make_shared<logging::DisplayConfigurationReport>(server.the_logger())},
 
131
      display_configuration_multiplexer{server.the_display_configuration_observer_registrar()},
 
132
      seat_report{create_seat_reports(server, options.get<std::string>(mo::seat_report_opt))},
 
133
      seat_observer_multiplexer{server.the_seat_observer_registrar()},
 
134
      session_mediator_report{
 
135
          create_session_mediator_reports(
 
136
              server,
 
137
              options.get<std::string>(mo::session_mediator_report_opt))},
 
138
      session_mediator_observer_multiplexer{server.the_session_mediator_observer_registrar()}
 
139
{
 
140
    display_configuration_multiplexer->register_interest(display_configuration_report);
 
141
    seat_observer_multiplexer->register_interest(seat_report);
 
142
    session_mediator_observer_multiplexer->register_interest(session_mediator_report);
 
143
}