Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ScreenLock implenentation for streams and Web inteface #167

Merged
merged 5 commits into from
Sep 6, 2017

Conversation

ppodhajski
Copy link
Contributor

No description provided.

@ppodhajski ppodhajski force-pushed the feature/Lock branch 5 times, most recently from b8198d2 to 35454ad Compare July 5, 2017 08:36
emit modified(shared_from_this());
}

void ScreenLock::_remove(QString uri)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const QString&

{
if (std::find(_streams.begin(), _streams.end(), uri) != _streams.end())
{
_streams.erase(std::find(_streams.begin(), _streams.end(), uri));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do std::find only once by storing the returned iterator

ScreenLock();

/** Close the specified stream. */
Q_INVOKABLE void closeStream(const QString uri);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please reorder the methods for API readability, something like:

lock();
unlock();
isLocked();

registerStream();
releaseStream();
deregisterStream();
closeStream();
getStreamList();

Also I am not sure if so many methods are needed (deregister and close?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in closeStream method I emit streamClosed(uri), to close a hidden stream, which is not needed in deregisterStream as the stream is closed elsewhere.

}
Clock {
displayedHeight: parent.width
height: width
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what happened to the contentActionButton? I think we should keep it!

height: 500

ListView {
height: displaygroup / 2
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

displaygroup / 2 ??

@@ -58,7 +58,8 @@ class MasterQuickView : public QQuickView

public:
/** Constructor. */
MasterQuickView(OptionsPtr options, const MasterConfiguration& config);
MasterQuickView(OptionsPtr options, const MasterConfiguration& config,
LockPtr lock);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For readability group options and lock parameters, leaving MasterConfiguration at the end.

@@ -62,7 +62,7 @@ class MasterWindow : public QMainWindow
public:
/** Constructor. */
MasterWindow(DisplayGroupPtr displayGroup, OptionsPtr options,
MasterConfiguration& config);
MasterConfiguration& config, LockPtr lock);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For readability group displaygroup, options and lock parameters, leaving MasterConfiguration at the end.

@@ -85,6 +85,9 @@ class DisplayGroupRenderer : public QObject
/** @return true if the renderer requires a redraw. */
bool needRedraw() const;

/** Set the ScreenLock replacing the previous one. */
void setScreenLock(LockPtr lock);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move up after setRenderingOptions for API readability

@@ -93,6 +96,7 @@ public slots:
QQmlEngine& _engine;
DataProvider& _provider;
DisplayGroupPtr _displayGroup;
LockPtr _lock;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep same order as in the API for readability: place it after _options

Q_INVOKABLE void lock();

/** Release the specified stream. */
Q_INVOKABLE void releaseStream(const QString uri);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

style: no const for param in header

@ppodhajski ppodhajski force-pushed the feature/Lock branch 4 times, most recently from 1386eda to 5920db6 Compare July 7, 2017 09:51
@ppodhajski
Copy link
Contributor Author

TODO: fix the RestServerTests and PixelStreamWindowManagerTests

sourceComponent: buttonDelegate
}
}
Loader {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Loader not inside the image?

doc/Changelog.md Outdated
@@ -3,6 +3,9 @@ Changelog {#changelog}

# Release 1.4 (git 1.4-dev)

* [167](https://github.com/BlueBrain/Tide/pull/167):
Tide can be locked now. It prevents unwanted streams from opening and
freezes HTML interface.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tide can be locked when doing a presentation. The lock prevents unwanted streams from opening and blocks interactions from the HTML interface.

@@ -271,7 +271,7 @@ BOOST_AUTO_TEST_CASE(hideAndShowWindow)
windowManager.handleStreamStart(uri);
ContentWindowPtr window = windowManager.getWindow(uri);

BOOST_REQUIRE(!window->isHidden());
BOOST_REQUIRE(window->isHidden());
BOOST_REQUIRE(!window->isPanel());

windowManager.hideWindow(uri);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reverse the order of the tests then, it is not very useful to hide a hidden window


BOOST_CHECK_EQUAL(response.toStdString(), "Forbidden");
BOOST_CHECK_EQUAL(responseGET.second, int(QNetworkReply::NoError));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check all the values: responseGET.first/second, responsePUT.first/second.
You should also validate that doing a PUT works before doing the block.

@@ -88,17 +92,27 @@ BOOST_AUTO_TEST_CASE(testServerReturnsSimpleContent)
const auto url = QString("http://localhost:%1/test").arg(server.getPort());
const auto response = sendHttpRequest(url);

BOOST_CHECK_EQUAL(response.toStdString(), "Hello World!");
BOOST_CHECK_EQUAL(response.first, "Hello World!");
BOOST_CHECK_EQUAL(response.second, int(QNetworkReply::NoError));
}

BOOST_AUTO_TEST_CASE(block_all)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test does not block all? Rename to block_put_requests?

@@ -141,6 +141,12 @@ void PixelStreamWindowManager::handleStreamStart(const QString uri)
return;
}

if (uri == "Launcher")
{
openWindow(uri, QPointF(), QSize(), StreamType::LAUNCHER);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a duplication of the line below! Do:

// external streams don't have a window yet, create one now
const auto streamType = _isPanel(uri) ? StreamType::LAUNCHER : ...;
openWindow(uri, QPointF(), QSize(), streamType);

then rename the existing _isPanel() helper function to _isLauncher()

@@ -47,7 +47,7 @@ using namespace zeroeq;
std::future<http::Response> HttpServer::respondTo(http::Request& request) const
{
if (_blockedMethods.count(request.method) &&
!_isWhitelisted(request.source))
!_isWhitelisted(request.source.substr(0, request.source.find(":"))))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the substring extraction deserves a local variable or a helper function for readability

BOOST_CHECK_EQUAL(response.second, int(QNetworkReply::NoError));
}

BOOST_AUTO_TEST_CASE(block_all)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this still does not test "block_all", merely PUT

return http::make_ready_response(http::Code::OK);
});

server.block(http::Method::PUT);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

test PUT works before block(). Test unblock().

ScreenLock();

/**
* Lock the screen. Notify about icoming streams and disallow
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notify about icoming streams?

Q_INVOKABLE void closeStream(QString uri);

/** Release the specified stream. */
Q_INVOKABLE void releaseStream(QString uri);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we had discussed and agreed to rename these acceptStream and rejectStream?

void registerStream(QString uri);

/** Get the list of registered streams */
QStringList getStreamList();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would call this getPendingStreams or getBlockedStreams


bool RestServer::_isWhitelisted(const std::string& source) const
{
return _whitelist.count(source.substr(0, source.find(":")));
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

source.substr(0, source.find(":")) needs to be in a separate method _getHostname(source)

@@ -0,0 +1,161 @@
/*********************************************************************/
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebase error? rm this file!

@@ -88,6 +88,7 @@ QJsonObject to_json_object(ContentWindowPtr window, const DisplayGroup& group)
{"fullscreen", window->isFullscreen()},
{"focus", window->isFocused()},
{"uri", window->getContent()->getURI()},
{"visible", window->getState() == ContentWindow::HIDDEN ? false : true},
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't things be simpler if we just omitted hidden windows?

@@ -64,6 +64,7 @@ public slots:
void updateRequestScreenshot();
void updateDisplayGroup(DisplayGroupPtr displayGroup);
void updateInactivityTimer(InactivityTimerPtr timer);
void updateLock(ScreenLockPtr markers);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ScreenLockPtr markers, right ;-)

@@ -82,6 +83,7 @@ public slots:
SwapSyncObject<InactivityTimerPtr> _syncInactivityTimer;
SwapSyncObject<OptionsPtr> _syncOptions;
SwapSyncObject<MarkersPtr> _syncMarkers;
SwapSyncObject<ScreenLockPtr> _syncLock;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please make sure that all the methods associated with syncLock are in the same order wrt. the others objects

@ppodhajski ppodhajski force-pushed the feature/Lock branch 4 times, most recently from 0c885a0 to 036f606 Compare August 8, 2017 12:30
Copy link

@rdumusc rdumusc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did I miss the unit tests for the ScreenLock class? ;-)

BOOST_CHECK_EQUAL(
response.second,
int(QNetworkReply::ContentOperationNotPermittedError));
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perfect!

@@ -57,8 +56,6 @@
*/
class RestInterface : public QObject
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You forgot the : public QObject!!

@@ -53,7 +60,7 @@ RestServer::RestServer(const int port)
: zeroeq::http::Server{zeroeq::URI{QString(":%1").arg(port).toStdString()}}
{
_init();
addToWhitelist("127.0.0.1");
_whitelist.insert("127.0.0.1");
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should must be in init(), otherwise it is not called by the default constructor!

Or more simply do it in the header:
std::set<std::string> _whitelist{{"127.0.0.1"}};

Or even simpler, since there is just one entry no need for a set:

bool RestServer::_isWhitelisted(const std::string& source) const
{
    return _getHostname(source) == "127.0.0.1";
}

@@ -94,9 +94,9 @@ MasterApplication::MasterApplication(int& argc_, char** argv_,
, _masterToForkerChannel(new MasterToForkerChannel(forkChannel))
, _masterToWallChannel(new MasterToWallChannel(worldChannel))
, _masterFromWallChannel(new MasterFromWallChannel(worldChannel))
, _lock(new ScreenLock)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since ScreenLock derives from enable_shared_from_this, please follow the same logic as for Options and Markers to enforce the creation of the object via a static create() method that returns a shared_ptr

/** Register a new stream to the lock. */
void registerStream(QString uri);
/** Request a new stream acceptance. */
void requestStreamAcceptance(QString uri);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider reordering the methods in the logical order they can be used, with the "positive" action first:

requestStreamAcceptance
cancelStreamAcceptance

acceptStream
rejectStream

@@ -167,7 +167,7 @@ class PixelStreamWindowManager : public QObject
*
* @param uri the URI of the streamer
*/
void streamAdded(QString uri);
void externalStreamOpening(QString uri);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documentation should mention that at this point the stream window it hidden and the user is responsible to call showWindow() or handleStreamEnd().

Also, this class has unit tests and this new behaviour MUST be tested properly.

@@ -72,6 +73,10 @@ class RestServer : public zeroeq::http::Server
/** @return the port of the server. */
int getPort() const;

/** Re-implemented handling of http requests from Server. */
std::future<zeroeq::http::Response> respondTo(
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this whitelist behaviour should be unit tested too

@@ -60,6 +60,8 @@ class ScreenLock : public QObject,
QStringList streamList READ getPendingStreams NOTIFY streamListChanged)

public:
/** Create a shared ScreenLock object. */
static ScreenLockPtr create() { return ScreenLockPtr(new ScreenLock); }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-> now make the constructor private

screenLock->requestStreamAcceptance(STREAM2);
BOOST_CHECK(screenLock->getPendingStreams().length() == 2);

screenLock->unlock();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

also check that calling unlock() emits streamAccepted() for each of the two pending streams


screenLock->rejectStream(STREAM1);
BOOST_CHECK_EQUAL(streamRejected, true);
BOOST_CHECK(screenLock->getPendingStreams().length() == 0);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please also check that calling rejectStream(STREAM1); a second time does not emit streamRejected.


screenLock->acceptStream(STREAM1);
BOOST_CHECK_EQUAL(streamAccepted, true);
BOOST_CHECK(screenLock->getPendingStreams().length() == 0);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please also check that calling acceptStream(STREAM1); a second time does not emit streamAccepted.

const QString STREAM2("Stream2");
}

BOOST_AUTO_TEST_CASE(test_locking)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good, this is testing the locked behaviour, now do a second test case for the unlocked behaviour

@rdumusc
Copy link

rdumusc commented Aug 22, 2017

Mostly good, except In ScreenLock some signals may still be emitted even when nothing changes. This should also be covered by the tests. I suggest we look at it together when you're back.

@ppodhajski ppodhajski force-pushed the feature/Lock branch 3 times, most recently from 480bcb6 to 174d2f6 Compare September 4, 2017 14:21
@ppodhajski ppodhajski force-pushed the feature/Lock branch 3 times, most recently from e61aea2 to 8661409 Compare September 5, 2017 10:03
@rdumusc rdumusc merged commit afa9f58 into BlueBrain:1.4-dev Sep 6, 2017
@ppodhajski ppodhajski deleted the feature/Lock branch September 6, 2017 08:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants