report_rom/clipboard: API transition

Issue #1987
This commit is contained in:
Norman Feske 2017-01-10 14:13:35 +01:00
parent 1cfeb41f14
commit 28d497549c
6 changed files with 208 additions and 148 deletions

View File

@ -35,6 +35,9 @@ class Rom::Session_component : public Genode::Rpc_object<Genode::Rom_session>,
{ {
private: private:
Genode::Ram_session &_ram;
Genode::Region_map &_rm;
Registry_for_reader &_registry; Registry_for_reader &_registry;
Genode::Session_label const _label; Genode::Session_label const _label;
@ -69,9 +72,25 @@ class Rom::Session_component : public Genode::Rpc_object<Genode::Rom_session>,
public: public:
Session_component(Registry_for_reader &registry, Session_component(Genode::Ram_session &ram, Genode::Region_map &rm,
Registry_for_reader &registry,
Genode::Session_label const &label) Genode::Session_label const &label)
: :
_ram(ram), _rm(rm),
_registry(registry), _label(label), _module(_init_module(label))
{ }
/**
* Constructor
*
* \deprecated
* \noapi
*/
Session_component(Registry_for_reader &registry,
Genode::Session_label const &label) __attribute__((deprecated))
:
_ram(*Genode::env_deprecated()->ram_session()),
_rm(*Genode::env_deprecated()->rm_session()),
_registry(registry), _label(label), _module(_init_module(label)) _registry(registry), _label(label), _module(_init_module(label))
{ } { }
@ -88,7 +107,7 @@ class Rom::Session_component : public Genode::Rpc_object<Genode::Rom_session>,
/* replace dataspace by new one */ /* replace dataspace by new one */
/* XXX we could keep the old dataspace if the size fits */ /* XXX we could keep the old dataspace if the size fits */
_ds.construct(env()->ram_session(), _module.size()); _ds.construct(_ram, _rm, _module.size());
/* fill dataspace content with report contained in module */ /* fill dataspace content with report contained in module */
_content_size = _content_size =
@ -160,6 +179,7 @@ class Rom::Root : public Genode::Root_component<Session_component>
{ {
private: private:
Genode::Env &_env;
Registry_for_reader &_registry; Registry_for_reader &_registry;
protected: protected:
@ -169,7 +189,7 @@ class Rom::Root : public Genode::Root_component<Session_component>
using namespace Genode; using namespace Genode;
return new (md_alloc()) return new (md_alloc())
Session_component(_registry, label_from_args(args)); Session_component(_env.ram(), _env.rm(), _registry, label_from_args(args));
} }
public: public:
@ -179,7 +199,7 @@ class Rom::Root : public Genode::Root_component<Session_component>
Registry_for_reader &registry) Registry_for_reader &registry)
: :
Genode::Root_component<Session_component>(&env.ep().rpc_ep(), &md_alloc), Genode::Root_component<Session_component>(&env.ep().rpc_ep(), &md_alloc),
_registry(registry) _env(env), _registry(registry)
{ } { }
}; };

View File

@ -57,13 +57,15 @@ compare_output_to {
[init -> test-report_rom] Reporter: open session [init -> test-report_rom] Reporter: open session
[init -> test-report_rom] Reporter: brightness 10 [init -> test-report_rom] Reporter: brightness 10
[init -> test-report_rom] ROM client: request brightness report [init -> test-report_rom] ROM client: request brightness report
[init -> test-report_rom] -> <brightness brightness="10"/> [init -> test-report_rom] -> <brightness value="10"/>
[init -> test-report_rom] Reporter: updated brightness to 77 [init -> test-report_rom] Reporter: updated brightness to 77
[init -> test-report_rom] ROM client: wait for update notification [init -> test-report_rom] ROM client: wait for update notification
[init -> test-report_rom] ROM client: got signal [init -> test-report_rom] ROM client: got signal
[init -> test-report_rom] ROM client: request updated brightness report [init -> test-report_rom] ROM client: request updated brightness report
[init -> test-report_rom] -> <brightness brightness="77"/> [init -> test-report_rom] -> <brightness value="77"/>
[init -> test-report_rom] Reporter: close report session [init -> test-report_rom] Reporter: close report session, wait a bit
[init -> test-report_rom] got timeout
[init -> test-report_rom] -> <brightness value="77"/>
[init -> test-report_rom] ROM client: ROM is available despite report was closed - OK [init -> test-report_rom] ROM client: ROM is available despite report was closed - OK
[init -> test-report_rom] Reporter: start reporting (while the ROM client still listens) [init -> test-report_rom] Reporter: start reporting (while the ROM client still listens)
[init -> test-report_rom] ROM client: wait for update notification [init -> test-report_rom] ROM client: wait for update notification

View File

@ -14,7 +14,7 @@
/* Genode includes */ /* Genode includes */
#include <base/heap.h> #include <base/heap.h>
#include <base/component.h> #include <base/component.h>
#include <os/attached_rom_dataspace.h> #include <base/attached_rom_dataspace.h>
#include <report_rom/rom_service.h> #include <report_rom/rom_service.h>
#include <report_rom/report_service.h> #include <report_rom/report_service.h>
@ -72,8 +72,7 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
{ {
Genode::Env &_env; Genode::Env &_env;
Genode::Sliced_heap _sliced_heap = { Genode::env()->ram_session(), Genode::Sliced_heap _sliced_heap = { _env.ram(), _env.rm() };
Genode::env()->rm_session() };
Genode::Attached_rom_dataspace _config { _env, "config" }; Genode::Attached_rom_dataspace _config { _env, "config" };
@ -87,7 +86,7 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
typedef Genode::String<100> Domain; typedef Genode::String<100> Domain;
Genode::Attached_rom_dataspace _focus_ds { "focus" }; Genode::Attached_rom_dataspace _focus_ds { _env, "focus" };
Genode::Signal_handler<Main> _focus_handler = Genode::Signal_handler<Main> _focus_handler =
{ _env.ep(), *this, &Main::_handle_focus }; { _env.ep(), *this, &Main::_handle_focus };

View File

@ -12,26 +12,37 @@
*/ */
/* Genode includes */ /* Genode includes */
#include <os/server.h> #include <base/component.h>
#include <base/attached_rom_dataspace.h>
#include <report_session/connection.h> #include <report_session/connection.h>
#include <os/attached_rom_dataspace.h>
#include <os/reporter.h> #include <os/reporter.h>
#include <util/xml_generator.h> #include <util/xml_generator.h>
#include <util/xml_node.h> #include <util/xml_node.h>
#include <timer_session/connection.h> #include <timer_session/connection.h>
namespace Test {
class Nitpicker;
class Subsystem;
struct Handle_step_fn;
class Main;
class Nitpicker using namespace Genode;
}
class Test::Nitpicker
{ {
private: private:
Env &_env;
Timer::Session &_timer; Timer::Session &_timer;
Genode::Reporter _focus_reporter { "focus" }; Reporter _focus_reporter { _env, "focus" };
void _focus(char const *domain, bool active) void _focus(char const *domain, bool active)
{ {
Genode::Reporter::Xml_generator xml(_focus_reporter, [&] () { Reporter::Xml_generator xml(_focus_reporter, [&] () {
xml.attribute("domain", domain); xml.attribute("domain", domain);
xml.attribute("active", active ? "yes" : "no"); xml.attribute("active", active ? "yes" : "no");
}); });
@ -46,9 +57,9 @@ class Nitpicker
public: public:
Nitpicker(Timer::Session &timer) Nitpicker(Env &env, Timer::Session &timer)
: :
_timer(timer) _env(env), _timer(timer)
{ {
_focus_reporter.enabled(true); _focus_reporter.enabled(true);
} }
@ -63,19 +74,19 @@ class Nitpicker
* *
* This function drives the state machine of the test program. * This function drives the state machine of the test program.
*/ */
struct Handle_step_fn struct Test::Handle_step_fn
{ {
virtual void handle_step(unsigned) = 0; virtual void handle_step() = 0;
}; };
class Subsystem class Test::Subsystem
{ {
private: private:
Server::Entrypoint &_ep; Env &_env;
typedef Genode::String<100> Label; typedef String<100> Label;
Label _name; Label _name;
@ -86,25 +97,25 @@ class Subsystem
Label _session_label() Label _session_label()
{ {
char buf[Label::capacity()]; char buf[Label::capacity()];
Genode::snprintf(buf, sizeof(buf), "%s -> clipboard", _name.string()); snprintf(buf, sizeof(buf), "%s -> clipboard", _name.string());
return Label(Genode::Cstring(buf)); return Label(Cstring(buf));
} }
Genode::Attached_rom_dataspace _import_rom; Attached_rom_dataspace _import_rom;
char const *_import_content = nullptr; char const *_import_content = nullptr;
Report::Connection _export_report { _session_label().string() }; Report::Connection _export_report { _env, _session_label().string() };
Genode::Attached_dataspace _export_report_ds { _export_report.dataspace() }; Attached_dataspace _export_report_ds { _env.rm(), _export_report.dataspace() };
static void _log_lines(char const *string, Genode::size_t len) static void _log_lines(char const *string, size_t len)
{ {
Genode::print_lines<200>(string, len, print_lines<200>(string, len,
[&] (char const *line) { Genode::log(" ", line); }); [&] (char const *line) { log(" ", line); });
} }
void _handle_import(unsigned) void _handle_import()
{ {
if (!_expect_import) { if (!_expect_import) {
class Unexpected_clipboard_import { }; class Unexpected_clipboard_import { };
@ -122,21 +133,21 @@ class Subsystem
_log_lines(_import_content, _import_rom.size()); _log_lines(_import_content, _import_rom.size());
/* trigger next step */ /* trigger next step */
_handle_step_fn.handle_step(0); _handle_step_fn.handle_step();
} }
Genode::Signal_rpc_member<Subsystem> _import_dispatcher = Signal_handler<Subsystem> _import_handler =
{ _ep, *this, &Subsystem::_handle_import }; { _env.ep(), *this, &Subsystem::_handle_import };
static void _strip_outer_whitespace(char const **str_ptr, Genode::size_t &len) static void _strip_outer_whitespace(char const **str_ptr, size_t &len)
{ {
char const *str = *str_ptr; char const *str = *str_ptr;
/* strip leading whitespace */ /* strip leading whitespace */
for (; Genode::is_whitespace(*str); str++, len--); for (; is_whitespace(*str); str++, len--);
/* strip trailing whitespace */ /* strip trailing whitespace */
for (; len > 1 && Genode::is_whitespace(str[len - 1]); len--); for (; len > 1 && is_whitespace(str[len - 1]); len--);
*str_ptr = str; *str_ptr = str;
} }
@ -146,39 +157,36 @@ class Subsystem
* *
* \throw Xml_node::Nonexistent_sub_node * \throw Xml_node::Nonexistent_sub_node
*/ */
Genode::Xml_node _imported_text() const Xml_node _imported_text() const
{ {
if (!_import_content) if (!_import_content)
throw Genode::Xml_node::Nonexistent_sub_node(); throw Xml_node::Nonexistent_sub_node();
Genode::Xml_node clipboard(_import_content, Xml_node clipboard(_import_content, _import_rom.size());
_import_rom.size());
return clipboard.sub_node("text"); return clipboard.sub_node("text");
} }
public: public:
Subsystem(Server::Entrypoint &ep, char const *name, Subsystem(Env &env, char const *name, Handle_step_fn &handle_step_fn)
Handle_step_fn &handle_step_fn)
: :
_ep(ep), _env(env),
_name(name), _name(name),
_handle_step_fn(handle_step_fn), _handle_step_fn(handle_step_fn),
_import_rom(_session_label().string()) _import_rom(_env, _session_label().string())
{ {
_import_rom.sigh(_import_dispatcher); _import_rom.sigh(_import_handler);
} }
void copy(char const *str) void copy(char const *str)
{ {
Genode::Xml_generator xml(_export_report_ds.local_addr<char>(), Xml_generator xml(_export_report_ds.local_addr<char>(),
_export_report_ds.size(), _export_report_ds.size(), "clipboard", [&] ()
"clipboard", [&] ()
{ {
xml.attribute("origin", _name.string()); xml.attribute("origin", _name.string());
xml.node("text", [&] () { xml.node("text", [&] () {
xml.append(str, Genode::strlen(str)); xml.append(str, strlen(str));
}); });
}); });
@ -192,7 +200,7 @@ class Subsystem
{ {
using namespace Genode; using namespace Genode;
try { try {
typedef Genode::String<100> String; typedef String<100> String;
String const expected(str); String const expected(str);
String const imported = _imported_text().decoded_content<String>(); String const imported = _imported_text().decoded_content<String>();
@ -219,12 +227,9 @@ class Subsystem
}; };
namespace Server { struct Main; } struct Test::Main : Handle_step_fn
struct Server::Main : Handle_step_fn
{ {
Entrypoint &_ep; Env &_env;
enum State { enum State {
INIT, INIT,
@ -268,7 +273,7 @@ struct Server::Main : Handle_step_fn
_state = state; _state = state;
} }
void handle_step(unsigned cnt) override void handle_step() override
{ {
log("\n -- state ", _state_name(_state), " --"); log("\n -- state ", _state_name(_state), " --");
@ -399,35 +404,25 @@ struct Server::Main : Handle_step_fn
} }
} }
Genode::Signal_rpc_member<Main> _step_dispatcher = Signal_handler<Main> _step_handler =
{ _ep, *this, &Main::handle_step }; { _env.ep(), *this, &Main::handle_step };
Subsystem _admin { _ep, "noux", *this }; Subsystem _admin { _env, "noux", *this };
Subsystem _hobby { _ep, "linux", *this }; Subsystem _hobby { _env, "linux", *this };
Subsystem _work { _ep, "win7", *this }; Subsystem _work { _env, "win7", *this };
Timer::Connection _timer; Timer::Connection _timer { _env };
Nitpicker _nitpicker { _timer }; Nitpicker _nitpicker { _env, _timer };
Main(Entrypoint &ep) : _ep(ep) Main(Env &env) : _env(env)
{ {
_timer.sigh(_step_dispatcher); _timer.sigh(_step_handler);
/* trigger first step */ /* trigger first step */
handle_step(0); handle_step();
} }
}; };
namespace Server { void Component::construct(Genode::Env &env) { static Test::Main main(env); }
char const *name() { return "ep"; }
size_t stack_size() { return 16*1024*sizeof(long); }
void construct(Entrypoint &ep)
{
static Main main(ep);
}
}

View File

@ -1,3 +1,3 @@
TARGET = test-clipboard TARGET = test-clipboard
SRC_CC = main.cc SRC_CC = main.cc
LIBS = base server LIBS = base

View File

@ -13,91 +13,135 @@
#include <base/log.h> #include <base/log.h>
#include <base/component.h> #include <base/component.h>
#include <base/attached_rom_dataspace.h>
#include <os/reporter.h> #include <os/reporter.h>
#include <os/attached_rom_dataspace.h>
#include <timer_session/connection.h> #include <timer_session/connection.h>
#define ASSERT(cond) \ #define ASSERT(cond) \
if (!(cond)) { \ if (!(cond)) { \
Genode::error("assertion ", #cond, " failed"); \ error("assertion ", #cond, " failed"); \
throw -2; } throw -2; }
static void report_brightness(Genode::Reporter &reporter, int value) namespace Test {
{ struct Main;
Genode::Reporter::Xml_generator xml(reporter, [&] () { using namespace Genode;
xml.attribute("brightness", value); });
} }
void Component::construct(Genode::Env &env) struct Test::Main
{ {
using namespace Genode; Env &_env;
Signal_receiver sig_rec; Timer::Connection _timer { _env };
Signal_context sig_ctx;
Signal_context_capability sig_cap = sig_rec.manage(&sig_ctx);
log("--- test-report_rom started ---"); Constructible<Reporter> _brightness_reporter;
log("Reporter: open session"); void _report_brightness(int value)
Reporter brightness_reporter("brightness"); {
brightness_reporter.enabled(true); Reporter::Xml_generator xml(*_brightness_reporter, [&] () {
xml.attribute("value", value); });
log("Reporter: brightness 10");
report_brightness(brightness_reporter, 10);
log("ROM client: request brightness report");
Attached_rom_dataspace brightness_rom("brightness");
ASSERT(brightness_rom.valid());
brightness_rom.sigh(sig_cap);
log(" -> ", brightness_rom.local_addr<char const>());
log("Reporter: updated brightness to 77");
report_brightness(brightness_reporter, 77);
log("ROM client: wait for update notification");
sig_rec.wait_for_signal();
log("ROM client: got signal");
log("ROM client: request updated brightness report");
brightness_rom.update();
log(" -> ", brightness_rom.local_addr<char const>());
log("Reporter: close report session");
brightness_reporter.enabled(false);
/* give report_rom some time to close the report session */
Timer::Connection timer;
timer.msleep(250);
brightness_rom.update();
ASSERT(brightness_rom.valid());
log("ROM client: ROM is available despite report was closed - OK");
log("Reporter: start reporting (while the ROM client still listens)");
brightness_reporter.enabled(true);
report_brightness(brightness_reporter, 99);
log("ROM client: wait for update notification");
sig_rec.wait_for_signal();
try {
log("ROM client: try to open the same report again");
Reporter again("brightness");
again.enabled(true);
error("expected Service_denied");
throw -3;
} catch (Genode::Parent::Service_denied) {
log("ROM client: catched Parent::Service_denied - OK");
} }
log("--- test-report_rom finished ---"); Constructible<Attached_rom_dataspace> _brightness_rom;
sig_rec.dissolve(&sig_ctx); enum State { WAIT_FOR_FIRST_UPDATE,
WAIT_FOR_TIMEOUT,
WAIT_FOR_SECOND_UPDATE } _state = WAIT_FOR_FIRST_UPDATE;
env.parent().exit(0); void _handle_rom_update()
} {
if (_state == WAIT_FOR_FIRST_UPDATE) {
log("ROM client: got signal");
log("ROM client: request updated brightness report");
_brightness_rom->update();
log(" -> ", _brightness_rom->local_addr<char const>());
log("Reporter: close report session, wait a bit");
_brightness_reporter->enabled(false);
_timer.trigger_once(250*1000);
_state = WAIT_FOR_TIMEOUT;
return;
}
if (_state == WAIT_FOR_SECOND_UPDATE) {
try {
log("ROM client: try to open the same report again");
Reporter again { _env, "brightness" };
again.enabled(true);
error("expected Service_denied");
throw -3;
} catch (Genode::Parent::Service_denied) {
log("ROM client: catched Parent::Service_denied - OK");
}
log("--- test-report_rom finished ---");
_env.parent().exit(0);
return;
}
}
Signal_handler<Main> _rom_update_handler {
_env.ep(), *this, &Main::_handle_rom_update };
void _handle_timer()
{
if (_state == WAIT_FOR_TIMEOUT) {
log("got timeout");
String<100> rom_content(_brightness_rom->local_addr<char const>()),
expected("<brightness value=\"77\"/>\n");
log(" -> ", rom_content);
if (rom_content != expected) {
error("unexpected ROM content: '", rom_content, "'");
_env.parent().exit(-1);
}
_brightness_rom->update();
ASSERT(_brightness_rom->valid());
log("ROM client: ROM is available despite report was closed - OK");
log("Reporter: start reporting (while the ROM client still listens)");
_brightness_reporter->enabled(true);
_report_brightness(99);
log("ROM client: wait for update notification");
_state = WAIT_FOR_SECOND_UPDATE;
return;
}
}
Signal_handler<Main> _timer_handler {
_env.ep(), *this, &Main::_handle_timer };
Main(Env &env) : _env(env)
{
log("--- test-report_rom started ---");
_timer.sigh(_timer_handler);
log("Reporter: open session");
_brightness_reporter.construct(_env, "brightness");
_brightness_reporter->enabled(true);
log("Reporter: brightness 10");
_report_brightness(10);
log("ROM client: request brightness report");
_brightness_rom.construct(_env, "brightness");
ASSERT(_brightness_rom->valid());
_brightness_rom->sigh(_rom_update_handler);
log(" -> ", _brightness_rom->local_addr<char const>());
log("Reporter: updated brightness to 77");
_report_brightness(77);
log("ROM client: wait for update notification");
}
};
void Component::construct(Genode::Env &env) { static Test::Main main(env); }