 Hi. Thanks for coming to my talk. Who of you is only here for the matrix talk afterwards? Don't worry, I'll be talking about matrix a bit as well. So hi, I'm Marcus. I'm a free software developer from Berlin. I've been working on the free Android ecosystem for the last two or three years. What does it mean? It means I'm using an Android phone that was at any Google services or Google Play Store, and I want to make that a more pleasant experience. So I'm an after I'd co-contributor and app maintainer. It's a full while. So who of you here is using an Android phone? Oh, wow. And who of you is using the Google Play Store or apps from the Google Play Store? About half or something like that? Yeah. That's what I'm trying to improve. So push notifications. They turn out to be one of the key missing pieces for free Android apps, apps that want to be published on Android, because currently there's, if you Google how to do push notifications on Android, you get that, yeah, use those Google services. Get into that later. So push notifications are when a server, a web app, web server sends unsolicited content to an app on your phone. That is without the app specifically asking for give me this update. It's also used for marketing purposes by proprietary apps a lot. So all of those newspaper, CNN, whatever application to, not really helpful push notifications a lot of the time. But it's also like a requirement for doing instant messaging or voice over P apps on your phone, because it's really no use if somebody calls you and your phone tells you half an hour later, oh, you got a call. So we need push notifications. So how do you send information from a server to a client without the client asking for it? Well, we cheat. We ask beforehand, give me new information at some point later, so we keep an open connection, which the server then can use to send those updates to the client. The problem is keeping a connection open does require maintenance of those connections. And that means battery power on mobile. Even more so on the varying network conditions, Flaky Wi-Fi, Flaky GSM network. So that means in turn that keeping it one connection open for every app on your phone that wants to receive push notifications to every one of their different web services. Well, that works, but it's going to drain your battery really, really fast. That's why Google introduced, well, Google Cloud Messaging and later Firebase Cloud Messaging, which bundles all those push notifications into one connection, which goes to Google Service. So your phone is connecting to the Firebase Service, we're just for receiving push notifications, and all those web services send their push notifications to Google Service, which then forwards it to your device. But as a number of drawbacks, for once, it requires Google Play Services being present on the device, which is the non-free part of Android. It also requires every app that wants to register for push notifications to include a proprietary library distributed by Google. So that actually means when you get free or apps, you thought you were free on the Google Play Service, which do Google Cloud Messaging, they're not actually free software, because they include a proprietary library or multiple ones. Well, that means all your push messages are sent through Google Service. Your false apps aren't actually false anymore. That includes Riot, Conversations, Firefox, Jami, NextLoud, DruckerChat. If you get them from the Google Play Service, from the Google Play Store. And there's also one other key drawback, because, well, Matrix and XMPP and DruckerChat and NextLoud are decentralized by design, so you can ask your own instance, or people, you can use instance of other people. But when the developers of the app built the APK of that app, they register for the Google Cloud Messaging Service, and they get a key from Google to send those push notifications through those Google Service to your device. And that key is tied to the APK. And you can't make it public, because as a West Google will just block it. So now you have to send your push, receive your push messages through two hops. From your own NextLoud instance, you send a push notification to a server hosted by the NextLoud app developers who forwards it to Google Cloud Messaging, who forwards it to your device. So now for an actually decentralized system, you introduce two centralized hops, which is not good. Or the alternative to that would be if you host the NextLoud instance, you have to distribute your own APKs of the NextLoud apps, which works but is a real hassle. So what are the alternatives if you don't want to use Firebase Cloud Messaging? Well, everybody builds their own more or less reliable solutions. Some protocols can do it better than others, like XMPP. They can do in-band push notifications, because they have a persistent connection anyway, that works reasonably well. But Android makes it quite hard to run background tasks. So it's a struggle. And the battery life is still horrible if you have all the different apps with all their persistent connections. So what do we want to do differently? Well, first of all, it's got to be free software, including server client library parts. It's got to be decentralized because we want people to run their own instances. And then we want users to be in control, which means the user of a smartphone can choose to push server instance. They want to register with, they trust to handle their data and metadata. And this push server instance is then communicated to all the different servers for corresponding to all the different apps on their phones. And we can also do why with this developer key requirement, because it's actually only used for accounting by Google. And as we are, want to be accountable to the user, not to app developers, we don't actually need APK to account, push account pairing. So you don't need this in the media rehab. So how does the architecture of this look like? Well, we have Android apps on your phone installed by user. They want to receive push notifications and they talk to some web service, which notify some or which they want to receive notifications from. The web service, it receives, well, when the app registers for push notifications, it gets a token. It's called push token. It sends this to the web service. And the web service that saves this push token. And whenever it wants to send a push notification to one specific app instance, it uses that push token as authentication. The app services sends this push notification through the push server, which is part of the open push project. So the push server has an API for the push client, which will come in a second, to register for push notifications. It generates those push tokens and stores the matching of a phone or a push client to the push token. And then it provides the API to the web services for receiving incoming pushes and then it forwards them to the push client. The push client in this model is the app running on your Android phone. It handles the registrations for pushes by other apps. It registers this with a push service. It's a part where you can choose which push server to use. And it's responsible for keeping the open connection to the push server. And whenever it receives a push notification, it distributes it to the other apps which have previously registered with it. So does it look on a picture? So the green parts are the things from the open push project. And the red parts are basically the users of this system. So this is your phone. These are the apps on your phone and every app talks to one server. So when you install an app, it registers to the push client on your phone. Ask it for a push token. The push client registers with a push server. The server generates a token, sends it to the client, sends it to the app, which then sends to the app server. And then you want to, when the app server then generates a push notification, it sends it the other way around to the push server, which sends it to the push client on your phone, which forwards it to the app on your phone. This connection here from the push client to the push server is the one that's kept alive by your phone. And so when you receive a push notification from it, it wakes up the app and the app then can then talk to the app server again and get more information or whatever. So that's the current status. There's the open API specification of the server part. That's roughly done, probably pending a few changes as we go along. It's the corresponding server implementation Python, which is kind of meant as a prototype for seeing this whole thing as viable. It's relatively since implementing the same API in a different language would not be that hard. Then there's an Android client implementation, which is still work in progress. Android is not or especially Android IPC talking different apps talking to each other is not the easiest to work with. I found so this is still ongoing. And then there's the corresponding client library, which other apps would use to register with push for push notifications on your phone. This is developed alongside the Android push client. It's also still work in progress. And then when we have the system, we need to, of course, integrate it in other communication platforms systems. And well, this is a to do for after the client implementation are finished. So how does it work in more detail? The connection between the push client and the push server is currently using server sent events, which has been tried out for custom build push notifications on Android. Server sent events are part of HTTP, following a very simple text based protocol, which you can send Jason blocks over. It's really simple. It works reasonably well in first tests. But the choice of the protocol is deliberately transparent to all users of the system. So we can experiment with having a different transport protocol later on, without impacting like any third party implementations. The push client is currently a standalone Android app. It's possible to integrate it maybe in micro g later on. People don't know what micro g is micro g is open source implementation of the Google play services on your phone, which does allow you to use Google cloud messaging without using Google play services on your phone. But it's still using Google servers and still requiring the proprietary app library. So it's not a very good solution for from a privacy standpoint. Or from a free surface standpoint. But micro g is already integrated in some Android ROM builds. So having this integrated in micro g would maybe make sense in the future. And I said earlier that it's getting pretty tricky, hard to keep background connections alive or any doing any kind of background work on Android. So for this, I choose the easy option with which is running a foreground service, which has a persistent notification for the user, which you can hide. But this is, I think this is okay for when it's one app that does it and it gets annoying when 20 different apps do it. The alternative would be running it as a system service like micro g does currently. Then you have the same permissions as running as a foreground service without needing the notification. And the client library communicates with the push client via Android IPC that's using a bound servers and then for incoming push it sends targeted broadcast events. This is basically modeled after what Google does for their own messaging. So where do we go from here? Well, we need to integrate it in, for example, matrix clients and servers rocket chat next cloud and see how it performs in practice under interesting network conditions. It's going to be interesting. One thing I've thought about is adding enter and encryption. Enter and encryption in this case would mean from the web service to your phone, the message being encrypted. So operators of push services are not, so for them it's not possible to read the content of the messages. They'd still get all the metadata, but that's what Google gets at the moment as well. But actually, we already have less metadata than Google because apps register with Google cloud messaging with their identity as an app. And Open push doesn't do that. So you would just, the operators push server would just see there's a message, then it would also be encrypted in the future. So there's less metadata. And I don't think it would be that hard to add famous last words because we only sending unidirectional messages and we don't want to keep any history. So it's just encrypt one with a key the client can use to decrypt it. I also want to experiment with different transports and service and events. Just that goes hand in hand to seeing how it works in practice with actual networks. And one other interesting thing that came up is having existing systems be the push provider for your phone. So if you're already running an XMPP client on your phone, you already have this persistent connection to your XMPP server because that's how XMPP works. So why couldn't we use this connection and just implement the push server API on your XMPP server as a push plugin and include a library in your XMPP client that would allow other apps to register for push notifications using the same APIs. And then, well, you have one less connection and hopefully the longer battery life. The interesting thing about that is then how to figure out if the user has multiple apps installed that could act as a push provider, which one gets selected and so he'll tricky user experience to figure out. I think that's it. This project I've worked on this for six months last year funded by German Government Institute through the prototype fund. And you can find more information on this website. Thank you. Thank you for your talk. We have time for, we have about five minutes for questions. Yeah, hi. Thanks for the talk. I would think the number one worry that I would have is that you won't get away forever with the foreground service. You said another option would be being, I mean, the thing you technically would want to be is a system app, right? So you wouldn't have that problem. I'm not sure, but are you worried as well? That's a way to become a system app, right? So what, can you? Yeah, I don't didn't get the exact question. Yeah, I'd be, I know right now the solution for you is to be a foreground service and you get the annoying notification if you don't configure it away. But I'd be worried as Android is becoming more and more restrictive with background tasks that, you know, two versions of Android from here. You might, this might, might no longer be the solution. So if I would have thought that's the main worry that you will one day fail at keeping alive in the background and providing a push service. Yes. So I think the only solution to set is being integrated on a system level, which is a means custom ROMs and people figuring out how to pseudo move some APKs around. But more ideally, it would mean that actually phone vendors would distribute non Google Android phones, which we are severely lacking right now. I wanted to ask it by the way, it's great presentation. And thank you. Thank you. I wonder how easy it would be for Google to make your solution impossible to use on Android. Again, yeah, how, how easy would it be for Google to make your solution impossible to use on Android? Well, we, if say block foreground services running forever, that's Ben makes it somewhat impossible if you depend on the stock Android from a bot in the store. They can still be workarounds for doing smart things with checking in every 15 minutes, however, often you're allowed. But they only can do things through the normal Android distribution. If you're not using any Google Play services and you're not getting your apps from the Google Play store, they can't really enforce any anyone not using this system through other means. There's the web API for push notifications. Have you thought about using the same API for the push server connection? I haven't really looked into web push, which I think is partly because it's a different problem domain because on desktop, you can get away with a lot less battery saving solutions. So what this is modeled after is Google's solution for push messages on the decentralized and free because while they have thought about this probably a long time. I once heard that that mobile ISPs have have special contracts with push service providers like Google or Apple that their TCP connections are not terminated relatively quickly like all the others. So have you done any measurements, any benchmarks on how efficient your service is? How often do connections get terminated and is this different from the Google implementation? I've not yet done any measurements, at least not with this. I've heard this quite often as well. I have never seen or heard anyone actually providing any data to back this up. So I consider this a rumor to know. It might be different in the US. I don't think it's the case. I'd be happy to hear input from you for that. So how does the push client check for broken connections because I tried to do something similar a few months ago using Autobahn and Crossbar and that as well running as a foreground service in Android and ultimately I had to send these Pings after every few minutes just to make sure the connection was alive and Android would complain that it's killing the battery. So the user would end up uninstalling that. So that was my biggest fear. So have you found a solution for that? No, well, the solution is check every X minutes where you can be a bit smart about how big X is. I don't think Android would complain more than, well, this notification you get with the foreground service as well. It's a bit, well, on Android you can hide notifications by long pressing on them. If you do that with a foreground service that is still running, you get another notification by the system which actually tells you this app is killing your battery. User education is the solution for this right now. This is how we can work. Okay, thank you very much. We are running out of time.