 About time, on my talk, I am Sree Kumar, I like to be called Sree, and welcome to this post-lunch session. I know this is a very cosy auditorium. Okay, so, how many people are sleepy? With show of hands, okay. How many people don't want to see code? And a show of hands. Oh, thank you. That's fine. So, this talk will be about creating services in Android, mostly the bare phones. And since the audience is just picking in and giving you guys some additional background, yeah, one more minute and we'll be ready to go. Where did you get the theme from? Point is gentium, plus, free for cinematic users. I think I spend more time creating the template when I get on the talk. I hope that doesn't show up on the talk. Maybe not, because I've been studying about this for a while in office. Hopefully it will all work. I can send you a template whenever you wish. It's not much of a template. So, gentium, some accession like that line, only they are made by these. Of course, I chose a font too, so, not that I made it. Okay, time to start. Is this mic directional? Hello? That's all. This is all you're going to buy? In a font. You don't have a mic and it's a manual? I guess I'm more comfortable with this, because the mic is in the direction. So, without further ado, I'm Shree, and I work as a software architect in annoying software. We actually are currently working a lot on Android. So, I'm not an app developer. I guess a lot of talks here would be mostly about apps, because that's where the majority of the activity is. I develop systems mostly. So, you won't see things like a fancy GUI, you might see some built-ups here and there. I'm mostly trying to illustrate the concepts that go towards creating services in Android. So, what's the motivation behind this talk? Does anybody else hear a feeble echo? Or is it just me? Nobody else? So, I proposed this talk out of sheer frustration, actually. So, I saw the talks that are up for submission, and I was struggling to make services on a new platform. Android, I started off three months back on this. My background is mostly C programmer, C++, Python, assembly language, even. I don't know Java. That doesn't mean that I consider Java as a blank language. I like Java, but people may not like my Java code here, but we keep those offline. So, the motivation behind this talk is that writing services is useful and fun. So, first, a service is a background activity which does a lot of work for you. And it's mostly a component that I should take in Android. And it's also painful. That's why I'm trying to give this talk here. This code is filled with a lot of code, and various UI, as I said earlier. So, just bear with me. If you're sleepy, that's okay too. I hope I don't break anybody's feet here. So, what's the deal with writing services in Android? So, you have a lot of documentation, but I don't think it's really enough. So, documentation for services, I firmly believe, shouldn't be like documentation for API, because once that happens, it becomes harder to write a service which actually does something. So, most of the documentation that I've found is scattered. A lot of places you see, Google searches for a lot of things. I've tried to collect all these things in one area. I'm not planning here to create something new. In fact, I haven't. I've brought together diverse pieces of documentation, combined it with my experimentation, and I'm going to present that to you. And documentation deals mostly with the mechanics. I don't know how much a fortified-minute session can make a difference in this area, but let's see. I'll give it a try. So, what's the objective of this talk? So, first, the classification of the term patterns that I've used. It's not designed patterns like the famous Shagali which he uses. So, don't expect that. This talk tries to give you a quick overview of AI again, which is Android interface definition language. So, we're mostly creating services based on the idea because they are the most hardest in my humble opinion. I've been working with them for a while now. So, I'll try to say what the features and the paints of working with these interface are. And I'll try to show you how you can write useful services as patterns. So, when you're trying to create a service, a background activity with which you want to interact in an application, you are mostly not too much concerned. So, as an application developer, you may be concerned with the exact thing the service does. But as a generic service writer, there are certain patterns that you can find useful that you'll find useful. And if you actually probe into the Android open source, you'll find a lot of these there. So, that's my attempt. I'll try to define services as some kind of patterns. I will only have one or maybe maximum two here because that's all the time we have. So, an introduction to Android services. So, the service concept if you pick one. So, how many people have written services here? Android services. Oh, very much people. I am going to be in trouble. Okay. AI game services, anybody? One, two, three. Okay. A few. Okay. Actually, part of this talk is to show you that it's maybe not that painful. Maybe not that painful. So, for those who are not aware, a service is an application component. So, pretty much everybody is aware of that. It's typically used for long running operations which are running in the background, but not necessarily. Like, I think everything gets in Android. The Android documentation is pretty clear about this. Unless the documentation says that they're creating a thread. They are not creating any. So, the same applies for concepts, the service concept. So, typically we associate service with threads, right? But if you create an Android service, and of course, I'll show you some more later on. So, just wait a minute. If you create an Android service, it will not automatically create either new classes or threads for it. And there are some classifications for Android services. Broadly, I classified it as either interaction based and based on application boundaries. So, this talk is about identifying the inter-process communication-based, AI-ideal-based services. Because I think that's the hardest part. It's also the one that we are least likely to use, but that's what this talk is all about. So, AI-ideal-based services. So, what's AI-ideal? Android interface definition language. It looks... An interface definition looks similar to an interface definition from Java. And there are tools in the Android toolkit which actually compile this into a separate code and create a service and create steps for you for marshalling and unmarshalling. So, when you're talking about service, in the generic sense, you have a client interacting with the server someday, not necessarily in the socket, right? And typically the two major concepts are marshalling and unmarshalling. So, you marshall something on the client side, you unmarshall it on the server side, then the server does something for you, it returns the result to you, right? So, AI-ideal is the way to easily do this on Android. And it's all about inter-process communication. I'm not going to deal with the simpler cases of the communication inside the process. But the samples that I'll show you will all be inside a single process. So, that's a kind of a dichotomy that I'll say later why I did it. So, if you read through the Android documentation, you'll see that there's something else with which you can create inter-process service, inter-process services. That mechanism is called messenger. So, messenger is based on manual multiplication of packets. So, you basically send a message from the process to another process, you have to manually take care of encoding and decoding the packet. So, I'll share it with you. Because I don't find it that rich and I have mostly done the idea because of its richness and its appropriateness to my work. So, why I'm going to obtain all the pain? So, if you read a little bit of AI-ideal, you'll see that it's not really recommended. There's this documentation around it. People say, don't try AI-ideal unless it's really necessary. So, I choose AI-ideal because it gives you natural interactions with the services. So, you basically connect your service and you write code which looks very much like code you use inside your program. And then you can interact with the service in a very natural program or like manner across processes where you can call the service and call you back. And you can pass complex objects as parameters. So, that's the reason to take on this pain. So, if you really don't have the need to take on this pain, maybe you shouldn't. Okay. So, first we looked at a hello service which I think is mandatory doing that more than half of the audience has done services. So, we'll jump right into the AI-ideal service so for those who actually already developed services you're probably already aware of on-bind and on-intense service and so on and so forth. So, okay, my image got chewed. All right, no problem. So, what does a hello service look like? So, a service typically, when you have a service implementation in Android, you need to implement a class which extends service and then you need to implement certain methods inside it. So, if you want a real service, you'll typically implement on-bind. And we'll of course come to the details of all this very quickly. And you expose a programmatic interface for your clients or for your consumers because by implementing methods, by implementing methods stops. So, you basically define an interface, you define a stop for the interface. So, the interface itself is processed by a tool and it generates additional code around it. And the interface communication happens using the binder drivers or more specifically the I-binder interface in Android. Of course, I will not go deeper into the I-binder interface because that's more complicated. So, services are exposed where Android manifest.x7. So, I hope everybody here has programmed with Android. Anybody who has not? Anybody who has not programmed in Android? Okay. So, mostly you have to export services where the manifest has the special nodes and all that. So, the client apps, you also write a service which explores on bind and exports its services where they manifest. Client types can bind via intents and they can use the services provided. And client apps can actually provide callbacks which the service can directly call you back. So, anybody who has done RPC, they're perhaps familiar with all these things. So, you call a service using a programmatic interface, the service calls you back with a programmatic interface. So, if the application wants to be called back by the service, it has to implement stops itself. So, typically the service implement stops. If you have client programs are doing the same, then the client also has to implement the stops. Okay. So, we quickly have a look at the service. Enough talk. So, this is a simple server which I have defined. It's called binding IPG server. So, to go through the documentation, you'll find that services can be binding or not binding here. Services can be binding or stopped here. So, binding IPG server which extends the service. Okay. And there's implementation of on-bind here, which you see. Okay. And it's basically returning an eye-binder. So, what's the eye-binder? I'm returning an API here. So, it's interesting to see what the API is. Oh. I'm very sorry for having you join. I should show you the eye-binder first. So, we are going to do a very simple service here. It was only one method which is start operation. Okay. And it can take a call back. So, basically, you're a client which will start a service and call something which will call you back. So, that's all. Because that mostly shows most of the things that we need for another service. So, it's very easy to see here. So, you just have an interface. It's a server API with a very simple definition. So, this will be noticed by the AI tool to generate more complicated code, which I won't show you, but I'll show you how to use it. Okay. So, we come back here. So, we take a server API, which is here. And we implement a stub for it. So, why is a stub? Because the ideal code generator generated code format. Now, that code itself will expect you to implement a stub so that you control the interface. You control what you do in your interface. So, our stub implements start operation, which takes the call back. Okay. And it does something inside it. Okay. The most important thing it does is it calls the client side itself. So, it takes the call back. It takes the call back. Okay. And it actually calls the call back a few times. So, what's the call back definition looking like? So, I showed you the server side interface. So, the call back definition of the prediction limits is that this is a single function which has a code. Okay. So, all by returns take a face, which the server exposes. Now, how does the client actually access all this interface? All right. So, it comes under manifest.xml, which actually exposes the service using the service tag. Okay. And it actually defines a intent free term, where it allows access to that, to the service. And the other thing is the most important one, is that we export the service. So, unwrite exported equal to true is what ensures that your manifest exports your service. Okay. So, that's mostly all to it. So, and on the client side. Right. So, we have a service column, which is an application, it's an activity. So, what it does is... Okay. So, here's its fun create of that activity. So, basically, the starting of the activity, you use an intent. So, I give the full name for the intent here, so that it doesn't clash with anything else. The whole name of the intent is here. And later on, you bind to the service, using bind service. And the interesting thing here is that there's service connection. So, what's the service connection all about? So, when you connect to a service, it's associated with the connection in which you can monitor the connectivity to the service. So, unwrite can kill processes when there's this memory and all that. So, you need to keep track of the connection to the service. Okay. So, what's inside the service connection? So, service connection itself has only two things inside. One is on-service connected, which is here. And the other one is on-service disconnected, which you see on the next thing. So, the on-service connected is called when your service is ready to service your request. And there, again, you have an eye-finder, like earlier. And that's costed to a server API. So, it's type cost to a server API, like here. Once you have that API, you have control over the service from the client end. And one thing about ITC services is that there's no way to predict which thread they'll run on when you are running across boundaries for Android AI services. There's always a thread pool. So, unlike other forms of Android development, where unless you create a thread explicitly, there's no thread which is started. Here is a pool of threads out of which one will be located. Something will come into your process randomly. So, you cannot, when you're interacting with a service, you cannot expect to be on the same thread as the UI. So, you have to typically use something like run on UI thread. If you have to update your UI as a result of interactions with the service. So, what we do is, on the UI thread we call it start operation. Actually, there's no great need for that, except that I want to update the UI. So, from here on, your interactions with the service will look like mixed with programming. So, you can see API dot start operation. So, looking at that, you cannot say whether it is, what do you say, local or remote, except that you have to catch remote exceptions. So, this kind of the gain of service program. So, you have to catch the remote exception because service can go in time. And, well, that's about all there is to a simple service. We are getting remote exception not caught. So, for that you have to use the... You have to catch remote exceptions. Not exception. That's the remote exception. Remote exception is that kind of the gain. Service dies on the other hand. You have to catch it. If you don't actually catch it, of course, you can't... You can't compile that. It's not that in the other hand. Okay, so, don't you have the slides? Do you think... Oh, no. I'll show you guys this in action. Actually, there's not much to it. So, we have a client app which is only here, and it starts the remote operation, and the remote operation exits immediately. But the server keeps calling you back on this slide. It calls it about 10 times here. The UI responds a little because the callback happens on different times in the UI thread. So, typically, your application does not respond for five seconds or something. It doesn't respond for three and a half seconds. Is that correct? I'm not dealing with much of the applications myself. So, that's all a simple demo of ours. Right? So, let's go back to... A little more about... Excuse me? Yeah? Can you go back to the server code where you're calling the callback which is faster? Can I go back to the server code where I'm calling the callback? Yeah. Can you tell me why you're creating another instance of the callback? Which one? The exact... This final server callback? Yeah. Oh, that's just so that I can access it from the inner class. You know, my Java is weak, so my colleague tells me that's the way to do it. So, that's what I do. Anyway, you're getting it from the parameter, right? Yeah, but I can't call it directly inside. I have to keep another method and just... I think some Java things are... And I don't need it in Java. I told you that. Yeah? What is the use of that thing inside the parameter? Which one? The area where it's fine. There's an in and a... Yeah. Right. So, that's getting passed back to the callback here. No, there is an in and a out. Yeah. Oh, okay. So, parameters can be in or in out or out, I think. So, most elementary parameters will be in by default, right? But you can have complex types which can be in and out and in out. So, if you have complex types, you have to define them. Those types have to implement passable. So, like this. That's all I can tell you now, sir. Because we have other stuff to cover. But does that answer the question? It's just... You can have any out or in out. So, they can also be in out. Yeah? Yeah? You talked about a thread pool. So, when the client made that call, API got something. Yeah. Does it return immediately or... The client returns immediately, yeah. Okay. That means that the UI is responsible. Yeah, that's what the UI is responsible. And if I call back the client in the same thread, without firing the thread, the callback will get invoked in the same context, which will be a UI thread context. Okay. So, it doesn't matter what... So, when you do API.start operation, what if the actual method was very long? Let's say it was a seek, a five-second seek. The client would still not... I mean, it's not actually a seek. The client... When I'm a little confused about the interaction over there, because it's a single install, is the role coming back to the client or...? The role is coming back to the client, yes. So, that's why a thread is doing the work part. If I had done the work in the same place, then the client would be waiting for the result. And there is a way. So, there's something called one-way. If you add a one-way parameter to the API, for interface, that won't happen. So, you get called and you'll be telling me everything. So, let's just write a deeper topic, please. Okay. So, I'll quickly go here because... So, what's so nice there? And so, there's also nice things you can call an application with easily. It looks like a program on the interface, except that you have to catch everything, et cetera. So, you don't have control over the binding. So, I didn't talk about it. Documentation doesn't talk about it. But on-wind, the return value is cashed. So, it's... Once the server is running, on-wind, it typically gets called only once. Okay. That came on a stop to me. I still haven't figured out why that is. But that's the way it is. So, that means you cannot change the interface. You have one interface, it takes too much for the lifetime of the service. So, that's... My opinion is not so nice. No control over that. So, you don't have any control over threading. So, there's another thread pool that I was talking about. Okay. The code is messier than it was in the interface. So, typically, if you call a function method, you don't really see a catch remote exception. I didn't talk about this here, but there's no support for exceptions across processes. So, you call a server method which raises an exception, then the service will die. And if the server calls a callback which raises an exception, the client will die. Exactly. Yeah. It's not even a matter. I guess I might have missed that. That's fine. But the summary is that exceptions are not passed back and forth across processes. And catching dead remote object exceptions results in a lot of messy code. And, of course, callbacks are involved in some thread pools so that complicates programming, which is already, I think, two questions around that area. So, because let's see if it's very complicated. And the last thing is there's no concept of versioning. So, once you explore the service, and that is used by multiple people outside your app, that's if you're dead. You have to keep track of that same function signatures for a while, unless you want to decide to break the compatibility. Okay? So, what are the common service patterns? Now, we'll come to... You know, typically, you have only sommetings that a service does. The internals and mechanics of what a service does. For example, you have a camera service. The camera service is a lot of work to do. But from an application interface point of view, it's calling you... There's a initialization. It keeps calling you back once every so many while when it has a frame, right? So, this kind of a pattern is what I call a lock pattern. Okay? There are services where simultaneous people would want access to shared resources. So, if you look up these kind of services you will find that the file failed, they fall under either serialized or a broadcast pattern. So, there will be some kind of serial access to some object underlying. And there will be some broadcasts. So, for example, you have sensors, right? So, you say... They just tell me as a listener. So, there might be multiple listeners to the sensor. In which case, this becomes a broadcast pattern. Okay? The less common thing, at least in the Android world, because of the limited footprint, is service versioning. So, as I say, you always have to maintain backward compatibility. That's also possible to provide. So, on-point returns an interface. Now, from that interface, you can control... You can provide control as another very interface. So, somebody who's familiar with... ...or... ...perhaps identify with this. So, you provide a very interface function, which itself provides you another interface. That will provide you some kind of service versioning. Of course, you can argue why such kind of things are required on mobile and Android devices. And if there's a need, it's possible to implement it. That's all I'm trying to say. Okay, so we look at the lock pattern for one-to-one time. Only, I guess. So, a bigger look at the lock pattern. So, lock... So, you have a lot of services where you can create and print a single object. And one process which needs to access the object. And that can be easily done by enforcing locking and unlocking behavior. So, a lot of people who don't know the modifier program are well aware of this. So, you lock the object. You use the object in some way, then you unlock it. And that looks very very simple. Except that, you know, there are questions like how do you handle multiple application access? What is the appropriate trading model for this kind of access? If... So, in Android, if an application locks something and doesn't go away, doesn't unlock the resource, then it would be very hard to make it... to make the same resource accessible by others unless the service is going to be a policy. Okay, leading to starvation. So, what we'll do is we'll look at a lot of service implementation, which is, again, some more simple code. It's nothing more complicated here. Actually, when I... When I gave the talk proposal, I had something very big in mind. Then I gave a similar talk to my colleagues in office and then I realized it was not possible to give a talk like this in 45 minutes or half an hour. So, I have to steal this down drastically. So, all the details that I'm not covered here, perhaps after my talk is over, for interested people, I can go outside. So, I understand this is a hard topic to cover. I can see a few sleeping faces and half you in it. Not too many. Okay, so, coming back. So, how does one implement a lock service? So, typically, what I do, I'm a systems guy. So, my idea of locks are somebody... So, client program wants to access the camera. So, the whole client process has access to the camera. So, that means I associate the locks with the calling process. Because there could be multiple threads set. Remember, there's a simple programming. There's a regular programming paradigm. If I gave you an object on which you can make calls, at the same time, I don't say that you cannot call it from different threads. So, I'm making ownership applicable to the process. That's what I typically do. There are reasons why I wouldn't want to do that. If you have a GUI, let's say, which is interacting with the same system in multiple viewports, for example, then there's no sense of ownership per app. It's more like ownership per thread. But this is a part of that I mostly developed here. And I use a worker thread for serialization. So, what do I mean by that? I was talking about a thread pool. So, now, remember, this anchor, right? And nobody says what is the size of the thread pool. Yeah. So, nobody says what is the size of the thread pool. So, in the emulator that I run, it's like three threads. Okay. And I haven't been checking my real devices. So, ideally, what you want to do is handle the threading yourself. And create any number of threads that you really want. So, typically, I find it very convenient to start threads on serialization. And I find that modeling IPC calls as producer-consumer problem. So, java.pro and java.preview.concorate, right? Which provides you easy ways to pass around data in a thread safe manner and with so many other patterns. So, I use that. And in the service implementation, I typically pass, in the service implementation, I typically do new work inside the function itself and pass around that data to the worker thread. So, that's something that you typically do in other kinds of services where it's equally applicable here too. Because you do not know what is the size of the thread pool. So, unless you want to take a chance, do more profiling of it and so on, I wouldn't advise that, okay? Do I have a solution for starvation which is applications calling the lock and not unlocking it? Actually, not. So, there's a way to... So, if an application dies without calling unlock, there's a way to evict those plans because you get dead object exceptions. But that's an implementation detail. So, it's hard to automate. It has to be applications of service decision policies. Okay? So, with that, let's have a look at... Quickly, I'll look at some code. I have a service here called X2 server which, again, has the same... a little different API. It has a lock where you actually decide to call back. There's a start operation which will result in calling of the power back and then unlock. It's as simple as this, okay? And the server power back remains the same like from the previous example. Oh, sorry. I think this is the wrong place. So, you again have a lock reserved which has an integer, right? As simple as that. So, how does our solution server change? Right? So, let's... So, we have a lock implementation here which is, again, a stop implementation. Okay? Server API.stop. So, what does the lock do? So, inside these procedures, you have... you get something called...get calling PID. You just tell you who the caller is. So, as I said before, I associate the PID with the lock. So... So, I ensure that if nobody has unlocked it or the owner is calling the lock again, then I allow access. Otherwise, I don't pass. Okay? So, that's the best thing that we can do, right? But it's very effective for the kind of things that you are doing in Android. I mean, this is not something which... which you are doing for some big enterprise applications and this is very simplistic. But it's very effective for this kind of environment. And unlocking also... actually, if the owner is calling the lock, then I clear over my... my own object, which actually pulls the lock. Okay? So, I have an operation called start operation, which is depending on... whether the caller is successful or not. Okay? Here, what I do is... I take the ownership with respect to the PID. Okay? If the ownership doesn't work, nothing for the caller return falls. Otherwise, I package everything inside another class, the operation, which is the integer that was sent from the client side. And I put it inside a word queue. So, I was talking about... java.com, I find it very useful. And array blocking queue. In this case, I have an array blocking queue with a single element. So, why is it a single element? So, this is where you control how many operations are handled by the thread. How many of them can be queued. So, that kind of thing. It can be anything you want. It can change the kind of paragraph you want to use here. So, I put it into a queue, which is a block array queue. And I have a thread, which is a worker thread, which is started on service startup. And it's only job. It's only for commands that are coming from the IPC. And then executing that. So, in this case, it slips one second and it calls the callback. So, as simple as that. It should be the synchronized instrument which is in just the right place so that takes care of any access issues and any multi-fitting issues happening there. And the service caller looks exactly the similar except the way it calls the API, right? So, it calls API.lock as a callback, which the implementation which I'll show later. And it starts an operation. And all this is happening in the UI thread trying to see run on UI thread. And let's see what the operation really does. So, the server ends up calling off-crisis and again on the UI thread we want something. So, basically, here we have a service which is implementing a lock. But I don't have multiple plans here. I'm not sure. So, that's a mistake I made. But I'll show you this in action. Again, as I said, there's hardly anything to show here because we'll just say, you know, what kind of something I got, right? So, that's the famous Android Inglater. Okay. So, that's it. I'll say it got called back. And you are the owner. And if you actually test this in multiple plans, you'll find that it actually works. So, I'll share all these words somewhere later. Yeah. I'll share all these words somewhere later. I don't have it here in the presentation. So, perhaps on my website later on. So, that covers the lock pattern that I was talking about. I don't think we have time for shared access service. So, I'll just put it up for any questions that you have. Any questions? Yeah. Thank you for calling our time late service. Okay. So, for example, we have a talk tomorrow. Okay. So, it's like a massive promotion. So, we've actually enabled a few devices on Android, right? So, if you look at the camera service, there's seven services. Typically, we find system services that have such great lengths to do things. Do things like IPC. So, that's one place where you're definitely deployed. Because one thing I didn't talk about here. What happens is, you expose these callbacks to the service as the clients invite. The question is, how does that client compile against your service? So, you need to have a job file somewhere. So, these things are messy for a critical application. It can be done, but it's messy. So, typically, you want to do it for simple applications. If you have some kind of great news that you want to do inside your application. Or if you want to create a system service, you'll do that. So, there are very specific needs. So, this doesn't take care of the remote procedure problem. This is all inside the same system. One never knows. When I release 7.0, you can have Android's communicating to other Android's using iBinder. No, not iBinder. Yeah, using iBinder. So, it's possible if you want it if you want to, but not with the supported tools. I think it's possible because once you have serialized it, the world is the end. So, you never know. Yeah, all that is very messy. Exceptions are tricky. One propagate across first boundaries. Any more questions? Yeah. Yeah, close enough. We can ask the client. You know, the system services stands at the boot up. If I want to add a new system service, can I do it as a third party of this network? No, not a system service. Of course, you can implement a broadcast receiver or something like that in standard service. See, it's not really dependent on that part of the infrastructure. So, if you have a system implementer, you have access to tools like init.rc. And you have access to the system server process. It actually starts a lot of process. If I'm part of that, if it is part of that, then it becomes like Android, you know, Android getting killed when there's no memory. If I don't want to have it. If an application is binding to you, you will be considered part of that application. So, you won't be killed. Most of that. I haven't seen the management that has happened. You understand, right? If a client has bound to the service, the service is considered part of the application. And it's not typically king or easy, or at all. The other thing is that Android says that when all the applications which have bound to a service, they can't find it. So, your service comes down, right? I mean, you keep open. Ask the question again. This service will only be in the time when all the applications which have bound to a service. Yeah. So, that's a matter of implementation. You can make it a start-up service. Can we override that? Yeah, you can. You can have something called a start-up service where you implement on-start and there's another way to do it. Now, how to, where should I mention that? Well, I think we're out of time here. Right? So, unless they can, they're dragging out ticking and streaming. So, you can make it right. Yeah. That's it. So, so I just thank all of you here for your presence. I hope it was useful. And I actually blog at my website, seek more of my answer and I'll put up the slides and report there for those interested. Of course, we can, we are obligated to take it offline. Let's just put it that way. All right. Thank you again everyone.