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:
Genode::Ram_session &_ram;
Genode::Region_map &_rm;
Registry_for_reader &_registry;
Genode::Session_label const _label;
@ -69,9 +72,25 @@ class Rom::Session_component : public Genode::Rpc_object<Genode::Rom_session>,
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)
:
_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))
{ }
@ -88,7 +107,7 @@ class Rom::Session_component : public Genode::Rpc_object<Genode::Rom_session>,
/* replace dataspace by new one */
/* 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 */
_content_size =
@ -160,6 +179,7 @@ class Rom::Root : public Genode::Root_component<Session_component>
{
private:
Genode::Env &_env;
Registry_for_reader &_registry;
protected:
@ -169,7 +189,7 @@ class Rom::Root : public Genode::Root_component<Session_component>
using namespace Genode;
return new (md_alloc())
Session_component(_registry, label_from_args(args));
Session_component(_env.ram(), _env.rm(), _registry, label_from_args(args));
}
public:
@ -179,7 +199,7 @@ class Rom::Root : public Genode::Root_component<Session_component>
Registry_for_reader &registry)
:
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: brightness 10
[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] ROM client: wait for update notification
[init -> test-report_rom] ROM client: got signal
[init -> test-report_rom] ROM client: request updated brightness report
[init -> test-report_rom] -> <brightness brightness="77"/>
[init -> test-report_rom] Reporter: close report session
[init -> test-report_rom] -> <brightness value="77"/>
[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] Reporter: start reporting (while the ROM client still listens)
[init -> test-report_rom] ROM client: wait for update notification

View File

@ -14,7 +14,7 @@
/* Genode includes */
#include <base/heap.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/report_service.h>
@ -72,8 +72,7 @@ struct Clipboard::Main : Rom::Module::Read_policy, Rom::Module::Write_policy
{
Genode::Env &_env;
Genode::Sliced_heap _sliced_heap = { Genode::env()->ram_session(),
Genode::env()->rm_session() };
Genode::Sliced_heap _sliced_heap = { _env.ram(), _env.rm() };
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;
Genode::Attached_rom_dataspace _focus_ds { "focus" };
Genode::Attached_rom_dataspace _focus_ds { _env, "focus" };
Genode::Signal_handler<Main> _focus_handler =
{ _env.ep(), *this, &Main::_handle_focus };

View File

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

View File

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

View File

@ -13,91 +13,135 @@
#include <base/log.h>
#include <base/component.h>
#include <base/attached_rom_dataspace.h>
#include <os/reporter.h>
#include <os/attached_rom_dataspace.h>
#include <timer_session/connection.h>
#define ASSERT(cond) \
if (!(cond)) { \
Genode::error("assertion ", #cond, " failed"); \
error("assertion ", #cond, " failed"); \
throw -2; }
static void report_brightness(Genode::Reporter &reporter, int value)
{
Genode::Reporter::Xml_generator xml(reporter, [&] () {
xml.attribute("brightness", value); });
namespace Test {
struct Main;
using namespace Genode;
}
void Component::construct(Genode::Env &env)
struct Test::Main
{
using namespace Genode;
Env &_env;
Signal_receiver sig_rec;
Signal_context sig_ctx;
Signal_context_capability sig_cap = sig_rec.manage(&sig_ctx);
Timer::Connection _timer { _env };
log("--- test-report_rom started ---");
Constructible<Reporter> _brightness_reporter;
log("Reporter: open session");
Reporter brightness_reporter("brightness");
brightness_reporter.enabled(true);
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");
void _report_brightness(int value)
{
Reporter::Xml_generator xml(*_brightness_reporter, [&] () {
xml.attribute("value", value); });
}
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); }