One major problem is, that the PreKey event (parsed by the filter class and distributed by the eventManager class) is not room based.
It can't be, because the room information is part of the encrypted content of the message (see below).
At the moment, every room object listining for prekey message events get the message, creates an olm session and decrypts it just to realize that this message might not be for him. I also think that it might cause problems due to the fact that multiple olm sessions are created with the same initial message (don't know if that causes issues, short workaround would be to remove the subscription as soon as you receive an correct olm message, however, this would cause problems if a olm session in future is renewed for this room)
Therefore, one idea would be to have a Encryption class that takes are of creating olm sessions and distributing the decrypted prekey messages to the relevant rooms. This Encryption class could also take care of the storing/pickling/loading of the room keys.
Also, the strict separation of lowlevel (JSON parsing) and highlevel is broken at the moment. The PreKey class accesses the JSON itself despite being a high level class. That's another reason for a lowlevel Encryption class.
{
"sender":"@ebnera:in.tum.de",
"sender_device":"IXSABTUFJC",
"keys":{"ed25519":"0Bk1QwAj2a4+E9ZNbL6szC0qj9JcScVIpdrNI5ZTowU"},
"recipient":"@fuhhbarmatrixtest:matrix.org",
"recipient_keys":{"ed25519":"qGUDoyysVcD3wgQZk6fu0aJNm01IeVn9m5WsJ09diok"},
"type":"m.room_key",
"content":{
"algorithm":"m.megolm.v1.aes-sha2",
"room_id":"!pvAiYjulqdNNXdjfHT:in.tum.de",
"session_id":"MEXyh8flJdc1nHRCbT6UEpM3ySL3lyVJk2lLkdN+sPA",
"session_key":"AgAAAAApKLafaR2+c+TS1pxnVeOIykeS4xiuABE7QDBofTGdUD0x7MvhCcYNyqsPWgtLzMuO+J+EK68KYY+HFaxY8cTOQgd/ZOGlCiSAa/+OhzDd/+Xk4f0mEkjehOVxQnPfWK1zTVhRKZN9DOUAXWtpfppbzaGX1tQz0LQVvDAflGR3DTBF8ofH5SXXNZx0Qm0+lBKTN8ki95clSZNpS5HTfrDwTHJAr0UN7w1aPMXi7H+rmeJxNZhmUQiptU9hmy6BF6ZpCHFEjN19s0TN2STAUF0oKkjeDnDZpU1okbVoBhOdCA",
"chain_index":0
}
}