 Hello, everyone. Thanks for joining this presentation. So today I'm going to talk a little bit about Android and how the Android open source project differs from other Linux distributions or embedded Linux distributions. So my name is Sergio Prado. I've been working with embedded software for a long time. Currently I've been working with Toradex. I'm the team leader of a project called Horizon. That's an embedded Linux platform based on containers. I have also my company and I've been doing a lot of consulting and training in the last years. I've been contributing to some of the previous projects also like the Linux kernel build route and the auto and sometimes I write some technical stuff at my blog at embeddedbits.org. So let's go directly to our topic here. I would say we have here four main objectives that I would like to cover in this presentation. So our idea here is to compare Android with another Linux distributions since we are in an embedded Linux conference. So we're going to compare what it's like to work with an Android on an embedded device and what it's like to work on an embedded device with Linux, a pure Linux system. So we're going to cover from the user perspective. So you are a user. What's the difference between working with an embedded Android and an embedded Linux system? You are an application developer. What's the difference between writing applications for an embedded Linux device and for an embedded Android device and also from a distribution container perspective? So you will port or create a distribution for an embedded device. What is the difference between creating this distribution for an embedded Linux system and for an embedded Android system? So we're going to try to cover these three perspectives from the user application developer and from the distribution perspective. And of course, to cover all of that, we need to understand the architecture of an embedded Android system. So we're going to talk a lot about the architecture and then we're going to compare with an embedded Linux system. If we think about what is an embedded Linux system or what is a Linux system in general, right? We have mainly three components. We have the bootloader that will basically boot the system. So it's going to be started by the hardware and it's going to load the kernel, possibly a hand-disk device trees and start up the kernel. Usually after the kernel starts, the bootloader doesn't do nothing and doesn't even stay in memory. And then the kernel boots and then the kernel will do all of the initialization and then mount a root file system and call the niche process. So the bootloader has the only objective to boot the system. The kernel has the objective which should manage the operating system and of course, you give some meaning to the system in the user space on where we have a lot of libraries and applications. We usually call this block, we usually call root file system, root, I guess. So we have mainly three blocks here, the bootloader, the kernel and the root file system. And when we go to an Android system, things are a little bit different, right? We of course still have the bootloader because we need the bootloader to boot the Linux kernel. Of course, we still have the kernel Linux, but with some extra features, we're going to talk a little bit about those features. And the user space of an Android system, it's very, very different from an Linux system and we're going to basically focus here in this presentation on the user space of an Android operating system. We usually call this the Android platform and that is the search code that Google provides in the package that they call the AOSP, Android open source project. Another way to view the Android is this diagram. So I removed it from the previous diagram, the first two blocks, the hardware and the bootloader to focus only on the operating system. So we have here basically two main components, the Linux kernel and the Android platform, the user space of the Android operating system. As we're going to talk a little bit about in the next slides, the kernel has some extra features to work with Android. But what Android is really different is in the user space. You're going to see that's really different in a lot of different aspects, like the way you manage the search code, the boot system is different, the tools that are used in the system, the libraries, the demons, most of the demons in an Android system doesn't have any sense on Linux, like it was really built by Google for Android. So although Google uses a lot of, I don't see if I would say a lot of open source components, but it uses some open source components, like some common libraries that we have in Linux, for example, OpenSSH or LibSSH, but most of the software components in Android comes from Google. Google really built the user space from scratch for Android. And we're going to talk about that in this presentation. I'm not going over the details right now because that's part of the presentation. But we can see here that we have three main layers in the user space of an Android system. We have in orange the native layer, where you have all of the libraries and demons, all of the code that runs outside the virtual machine. We usually call them the native layer. On top of the native layer, we have the Android framework. That's what we call those red blocks. Those are the framework. Basically, all of the business logic of the Android operating system are inside this framework. We have the virtual machine, the system services and the APIs. And on top of that, we have the Android applications. That's usually what we as a user or developer see the API. But there is a lot of things going on and we're going to talk a little bit about in this presentation. So let's start with the kernel. So what's the difference between a kernel that we run in our Linux distribution or an embedded Linux distribution that we build with yacht or build hoods? What is the difference between the kernel that we run on Android? It's of course the same kernel, but it is a downstream kernel. It's a kernel based on the mainline kernel. And we have some features that we need to run Android. I don't have time to talk a little about all of the features or all of the main features because I will focus here on the user space. But it's good to mention some features that we need to enable in the kernel to run Android. One of these features is the binder. Binder is the IPC, the inter-process communication and the RPC, the remote procedure call implementation in kernel space for Android. We're going to talk a little bit about the binder. How does it work later? But for now, it's good to know that binder is the main... it's really part of the operating system. Everything that happens in Android goes via binder. All of the communication between the process goes via binder. So it's really, really part of the operating system. We didn't need binder to have an Android system working. The other piece of software that we need in the kernel for Android is Ashman. Ashman stands for Android Shared Memory. It's basically the shared memory allocator for Android. For some reasons, Google decided to not use the POSIX implementation of shared memory inside to have its own implementation. And that's why we have Ashman. Another feature that's worth mentioning is the low-memory killer. That's basically an implementation in kernel space of low-memory manager. It is implemented on top of the out-of-memory killer, the default low-memory manager of the Linux kernel. And for some reasons also, Google decided to change a little bit how the out-of-memory killer works. For example, the out-of-memory killer will kill a process when the system is out of memory. The out-of-memory killer will use some algorithm to decide which process should be killed and will just kill the process. And that could cause problems in Android because you cannot kill any process in Android. Some processes are very important. So you should have ways to, for example, disable the out-of-memory killer to kill a specific process. So the low-memory killer adds some new features to the out-of-memory killer, some new rules that are used in Android. These are three examples of changes that were done in the kernel for Android. And there is a repository, a kernel repository, that they call kernel-common repository with all of the patches to run Android. The fact is that today the mainline kernel have the needed features to run Android. So today you can download the mainline kernel and enable those features and boot an Android user space on top of it. But there are more patches than that. Usually Google uses the LTS version of the Linux kernel, so this is the image of the branching model of the Linux kernel. It's available in the Android website, search.android.com. Here we can see that Google takes mainline LTS kernel and then creates a branch for an specific Android release and develop on top of this branch. And it keeps rebasing this branch when new LTS versions are released. And yeah, there are a lot of changes that Google applies on top of the LTS versions. So if you clone the kernel-common repository from Google and search for commits with the message that starts with Android, that's a standard that they created. So all of the commits that start with Android were applied for Android you're going to see for Android 11, the last release version, we have more than 1,000 patches for Android. Not that all of those patches are required through Android, right? Because there are a lot of patches that comes from partners, telecom providers. But yeah, we have a lot of patches. Some of them could be important or could provide some feature that a new version of Android needs to run. So usually when we are porting Android through a hardware platform, usually we expect from the silicon provider a BSP with a Linux kernel with the Android patches applied. Sometimes you don't get this version with the Android patch applied. So we have to get this kernel-common repo or to re-peak the patches or rebase. We have to apply those patches to have all of the features that we need for that release of Android. So yeah, we talk a little bit about the kernel and how it differs, right? So we need some specific features in the kernel to run Android, like Binder and Ashman. Now let's focus on the user space, what we call here the Android platform. So the Android platform is the user space part of an Android operating system, and it is provided by the Android open source project. The Android open source project is made up of hundreds of repositories. So if you download a version of Android, for example, the Android 11 uses more than seven hundred and eight repositories. So the project is composed of hundreds of projects, right? And that's why they created, when I say they, I mean Google, they created the tool called a repo that helps to manage this project that describes the project, right? So we have a XML file with the list of the projects and you use this tool called repo to download or to clone those repos. So basically these two lines, repo init, repo sync, basically these two lines will download the latest version of Android. It should take a while because it's a lot of search code. So the repo init will clone a repo and do some setup and the repo sync will go over all of the projects, describe it in a XML file and will clone those repositories in our machine in specific directors. So in the end after several hours you're going to have all of the search code of Android in your machine. So Android 11, for example, the search code is around 100 gigabytes of disk. And when you do a build, it's going to take more, more than 100 gigs of disk. So yeah, Android uses a lot of disk space because the search code is huge. That is the listing of the search code and here we can see one of the differences because when you think about when you are working with an embedded Linux device, for example, we are working with the build route or Yachtool, we don't have this structure of the project, right? Because here we have all of the search code of all of the user space. Everything is here. That's why it's 100 gigabytes of disk. And that's not common, right? It's like a big huge application. And of course, that's not how it works because we have here more than 700 repositories with search code from different projects. But the final view that we have is that a really huge application that you build with make. And we're going to talk a little bit about the build system. So we have everything here, all of the software components to build the images for an Android system. Everything is here, organized in those repositories. I usually say that the open source, the Android open source project is open and somewhat also closed because from the perspective of the community, it's open because you have access to the developers and the community. We have discussion groups and then we can use those discussion groups to talk to people, talk to developers. We can contribute to the project. So Google developed this tool called Garrett. It's a kind of code review tool. We can submit patches using this tool. Those patches are going to be revealed from someone and we can fix bugs in Android or maybe add a new feature. So from this perspective, the Android is an open source project, right? But when you think about it, the development of the operating system is closed because, for example, Google for sure is developing already the Android 12, but we don't know what's happening, what's being developed. We can contribute to Android 12 until they release the search code next year. So the development of the project is happening at closed doors. We don't know what's happening until they open the search code. So from that perspective, it's a closed project, right? They open and release the search code when they feel they can do it. And that, of course, differs from an embedded Linux device where you have all of the search code and you can contribute with any project, right? Also, there are some differences in licensing. Google doesn't like GPL and its variations. So we're going to talk a little bit here and give some examples. So the vast majority of software components in Android are permissive, uses permissive licenses like Apache, BSD. There are some GPL licenses, yes, but very small compared to Apache and BSD. And of course, there are closed components in Android, especially the Google applications, right? All of the applications are closed. You don't have the search code. If you want to add to our device, for example, Google Play, Google Maps, you have to certify your device and there is a process for that to be able to say that your device is an Android-powered device. Let's talk a little bit about the system. So, yeah, we have today Yoctop Embedded Beauty Hood. So Android uses one of those two build systems. No, Android has its own build system. In the past, the build system was basically based on make files. So you had hundreds and hundreds of Android.mk files in the search code. But during the development of Android, they start having some shortcomings. For example, the time to build Android starts to increase. They start to have some problems debugging the build system. So they decided to replace with the build system that they call its song. So this build system is different from what we are used to, right? So in Beauty Hood, we basically have a build system that is based on make files in the Yoctop Embedded. We have a build system that are based on Recipes, and we have the Beauty Bake tool to process those recipes and other metadata. In Android, it's very different. So right now, we still have some make files in Android, but they are moving the make files to another file called Blueprint file. So we have a lot of Android.dp files in the Android search code. It's a file with a JSON syntax. The idea of these files is to make it possible for you to define how a software component would be compiled. So how would you like this library to be compiled? This application could be a Java application, a C++ application. So you describe how the software will be processed using those files, right? Just like you take a Beauty Bake recipe and describe there how that software component would be processed with that recipe. That's the same thing, but with another language. That's the Blueprint language. And you have the Blueprint tool that will process those Blueprint files to produce another file called Ninja. And then the Ninja file will be processed by a tool called Ninja that will generate the software components that will really build, do the build. Of course, they didn't move all of the make files to Blueprint files. So it's kind of a transition yet. So to still keep supporting the make files, they created a tool called Catty or Katie. I don't know how to say. I think it's Catty, but so this tool will take the make file and then convert to Ninja files. Just like the Blueprint tool, take the Blueprint file and convert to Ninja file. I have here just to show you what is like this file. So this is Android.NUK file. It's really simple, right? You describe the search code in a variable called localServiceFiles. You describe the name of the module that you want to generate in a variable called the localModule. And then you'll say what you want to do in the end of the file with a macro here. It calls Build as Equitable. So here we are saying to the Android build system, take this helloword.c and build it and generate a helloword binary with it. And if we use a Java file there, it's going to use a different tool. Based on the file extension, it will know what the build system will do with that. And of course, the build type also makes a difference here. So yeah, it's very simple if you think about it. Of course, there are more complex examples, but the idea is to describe how to build software with those files. And that's the same here. But here we have a separate file. It's more simple than the make file, I think. It's I really prefer this version. So you describe what you want. I want to build a binary and then inside describe the parameters to build that binary. What would be the name of the binary? Where are the search codes? If you want to link to other libraries, you have to save here. And yeah, it's, again, simple to write. And there are documentation to write those files. So in the end, that's basically how the build system works. We have basically two tools, the blueprint tool that will take the blueprint files and generate Ninja files. We have the cut tool that will take the Android NK files and generate Ninja files. And the Ninja file that will be processed by the Ninja tool that will create the end of the binaries. Very different like if we compare to build system like Build Your Root or Yocto Open and Edit. In the end, we have the image and built in Android, basically what we have in this slide. We search a script that will set up the environment of the terminal. Then we have available some tools. One of these tools is the launch tool. You select what they call a product with the launch tool. It's a kind of when you are working with Yocto you have to set up the machine and the gesture. When you are working with Build Your Root you can load the dev config that describes what for which board you are trying to build that Linux system. And for Android, you launch you use the command launch to configure the terminal with the variables that will define for which product you want to build Android. Then you run by make then you wait several hours in the end to have images. Usually when we work with an embedded Linux system we have three or four images at most we can have the bootloader, the kernel with device trees, and then the root file system. In Android we have a lot of different images. We have, I'm going to talk a little bit about it, but we have the system product, vendor, OEM user data, cache and every image has its purpose. Organization of the root file system there is a kind of standard, right, when you go to Debian Fedora, you could see some differences, but the organization of the root file system is pretty much standard. You have on all of those Linux distributions, you're going to have the bin director the sbin director, the user director the lib director and everything. That's good, right, we have a standard. So Android follows that standard, right? No, Android doesn't follow that standard. So if you list the root file system of an Android system you're not going to find an sbin director and user director a lib director in the root file system. Of course we have the lib director, but it is inside the system directory. So we have this slash system slash lib, but not slash lib. So it's different, right? The root file system differs from a typical embedded or Linux system. And if you look at the partition layout, you have a lot of partitions in Android. Here I have two slides because from Android 10 on, it's a little bit different. They are not using the run disk as the root file system. So until Android 9 we have a run disk that will be mounted as the root file system and inside there we're going to have in its script that will mount the other partitions in Android 10. And now 11, we still have the run disk because it's necessary so the system partition can be checked with the enverity, but the run disk is not the root file system anymore. And why do we have all of those partitions? Because Google is worried about the changes in the base operating system. So the system partition would be the base operating system. What comes from Google? But we have another players in Android, right? We have the silicon provider, for example, Qualcomm. We have the device manufacturer, for example, Samsung. We have the telecom provider, for example AT&T. All of those players would want to change this in the operating system. So we have the system partition to Google. We have the vendor partition for the silicon provider. We have the ODM partition for the device manufacturer and we have the product partition for the telecom provider. Every player could do his own changes in his own partition to not mess up with other partitions. And that would, in theory, improve, for example, the ability to update the system. So that's why we have a lot of partitions in Android. Another thing that's the right difference from an embedded Linux system is the connection with the device, right? So usually on an embedded Linux system we have a serial connection with the device, but if we take an Android device, especially a mobile device or a consumer device running Android, we don't have visible accessible serial part. So Google tried to show that problem with a tool called ADB. So that's a tool that was created specifically to run on Android, although we have part to run on Linux. The ADB tool is composed of several components. We have the tool that you run in your development machine. So you run ADB in your development machine. It will talk to a server in your machine because the idea of the server is to make it possible to communicate, to have a lot of clients communicate with the same device. And then on the target you have a gadget driver to receive the packages from your host machine and pass those to the deal that is running in Android that will execute the comments that you're asking. So you can do a lot of fees with ADB. We can list the devices with ADB devices. You can pull or push files so you don't need SSH and Android. You can use ADB to transfer files between the target machine and the host machine. You can open a shell if you run ADB shell, you can open a shell and have access to your device. If you are running a development build, they call it angel build, you have root access and then you can do everything you want in the device. But of course if you try to do an ADB shell to a mobile device, you won't have root access. You have shell access and not much can be done there. Very nice. So far we talked a lot about the source code, how it differs the build system. Let's talk a little bit now about the native layer. The native layer, we call it native because it's running outside the Java virtual machine. So mostly code written in C++. Let's talk about some differences that we have in the native layer of Android compared to a Linux system. First difference is the C library. So the C library is our API to the kernel. We have a lot of C libraries in Linux. So Android must use one of those C libraries, right? Of course not. Android uses his own C library and let's call it Bionic. I can see three reasons why Google decided to use the C library. The Bionic has a C library license, speed and size. Google doesn't like GPL, right? And GLEBC and USBBC are both GPL. Maybe Google could use Muscle, but I think maybe at that time, three years ago Muscle was not ready yet for production. So maybe that was the reason they decided to not use Muscle and they decided to create or maintain his own C library. As far as I remember it was based on a BSD C library. The only thing about the Bionic is that it's not really POSIX compliant. So if you try to build a Linux application on Android, you could have problems. Just an example this is a snippet of search code from Beesbox. The last version of Beesbox. If you grabbed for Android there, you're going to find some if that's inside the search code. So if that Android does this and not that because there are some like some missing APIs in Android or some differences in the behavior of some APIs in the Bionic. So we have to adapt to our software to the Bionic library. Another difference that we can see in Android that we don't see in Linux, in embedded Linux system is Beesbox. Beesbox is a very common tool, almost every embedded Linux device has Beesbox installed. Beesbox provides a lot of common tools for an embedded device. But Android doesn't use it. Probably because it's GPL. So Android Google started developing his own version of Beesbox called 2box. Then after a while they decided to develop their own, they decided to adapt a community implementation called Toybox. That's developed by Robert Lendley that was one of the maintainers of Beesbox. But he's not a memoir. The fact is that Beesbox has a lot of tools. So this is a listing of the Beesbox tools. And if we take the listing of the 2box and the Toybox like it's kind of a half of what we have in Beesbox. So usually when I'm working with an embedded Android device I usually install Beesbox because for example if you want to run VI in the device you will need Beesbox because you don't have VI in 2box or toybox. So yeah VI is just an example. But there are a lot of tools that Beesbox provides that these tools doesn't provide. It's just a matter of changing the build system to include Beesbox, to build and include Beesbox in the image but you have to do it because it is not available by default. In its system, so in its system is another part of Android that is very different. So you would expect that Android will use a common in its system like system 5 in each or system D. And it's very different in a lot of different ways. So yeah, it's a new system. So it will do the start up of the system. It will start and manage the demons. It will do some other things like manage system properties. But if you configure, it's different. It's not like that you set up some shell scripts and you're done. It has its own syntax. So in the boot they need to demo. We'll read some in its scripts. Those are files with rc extension. And then we'll process those in the scripts. And they are very different. They have declarations of actions. For example, here we have this action. So when this action happens, when this action is triggered, you have to execute these commands. Here I have more examples. When this action is triggered, you have to execute those commands. And you can see those commands are not shell commands. They are in each specific command. So we don't have a synlink command in the shell, right? If you want to create a synlink command, you have actions and commands. And during the boot they need to process. We will trigger those actions and we'll run those commands inside those actions. You will have also declarations of services. It's like GMOs. When you declare a service, it doesn't mean that the service will run, but it means that this service exists. To run the service, you're going to have to use the start command, for example. So we start with entity. We'll run this demo with these options. So, yeah, we could have a whole presentation all focused on this, but yeah, we don't have time here to talk about it, but I just want to mention that it's very different. Another thing that is different than Android is the shell. It's very... Well, shell is a shell, right? If you, for example, try to run a shell script that you run in Ubuntu, for example, or Dabian. If you try to run in Android, you could have problems because it's not... You're not running the born-again shell or any other shell implementation in Android. You're running the mere PSD shell. That's a more limited shell implementation. We have also a lot of demons in Android, those processes that run in the background doing something. But if we take a look at the demons in Android, we're going to see that they are very different. So most of the demons in Android, we don't have in Linux. The Android basically have a re-implementation of a lot of demons that we usually have in Linux. For example, in Linux, we have the Udab demo to manage hot-plugging of devices. In Android, do we use Udab? No, we have another demo called UventD. We have a demo to manage storage devices, devoted demo. We have a demo to manage communication with the radio. We have a demo to manage the networking, so we don't use network manager or call man in Android. We have a specific demo for that. All of those demons were developed by Google. So if we list the process running on an Android system, we're going to see a lot of different demons that we don't even know about it, because it's really specific to Android. That's the same with logging, right? We have a specific log with Android. Android doesn't use syslog or journal control for logging. It has a specific demo called log-id to do the logs. And this is the output of the log in Android. You just run log catch and you have everything done. I really like the login system in Android. It's very well done. And to finish this native layer, it's good to talk about the native layer. So in Linux, if we think about it, we don't have any extra abstraction, usually, to talk to the hardware, right? So we have the hardware. We have drivers in the Linux kernel, the export interface, slash sys, slash dev. We could have some library on top of it and then the applications use those libraries. On Android, it's very different. So with this diagram, it's very important to understand Android in this presentation. So let's say, for example, you want to talk to a serial port. On an embedded Linux system, you have the slash dev slash tty. You can open this file and talk to this file. On Android, it's very different. So imagine on the Android app, we want to talk to this device. You're going to have to talk to an API. So we have to talk to use an API. That API is going to send a message to a service running inside the Android framework. That's going to talk to a hardware abstraction layer for the serial port. That's going to talk to the hardware. So every layer here has its responsibility, right? The API, the responsibility of the API is to provide an abstraction for the application. The functions to access the device. The responsibility of the service is to make it sure that the application can access the device so it checks permission. It will manage to access the device because all of the access to that device will go over the service. And the last layer will provide an abstraction to the hardware. So if you change the kernel interface, you change the abstraction here and then the service will keep running. So yeah, in Android, it's very different in this sense, right? We have a lot of layers and of course an application here could access directly the device, but you would bypass all of the rules that Android and Google defines. The permission, the security, the abstraction and everything else. So if you want to support a device in Android, you will have to develop, if you want to follow the process, you will have to develop a hall for the device, a service for the device and possibly an API for the device. And yeah, it's very different, right? All of the communication in Android occurs via Binder. So Binder is the implementation in kernel space for communication between process. So we have one process wanting to talk to another in our case here, we have the service that wants to talk to the hall. So here is going to exchange messages and then it's going to use Binder to exchange those messages. We are finished with the presentation. So let's talk a little bit about the framework and then we can finish the presentation. In the framework, that's where we really have the business logic of Android. The system service has all the logic have all the logic to access the resources provided by the operating system. So we could have harder resources or system resources. For example, sensors are resources. Powers are resources. Batteries are resources. Cameras are resources. Every resource has a service in the framework. The service provides an API. It provides a remote access or interface that you can talk to, that you can consume. And the APIs will talk to those services, to use those services. We have in Android 11 184 services. It's a lot of services. And most of those services. So again, that diagram. Android for example wants to talk to a sensor. It's going to call a sensor API. That's going to send a message to a sensor service. That's going to abstract the access, centralizes, manages concurrency and then checks permission. After that, it's going to call a call. That's going to abstract the access to the hardware. That's how Android works. If you think about it, it's very different from a Linux system. What is nice about Android that we have a lot of tools in the command line that we can use, for example, if you want to do a call in the command line, you can just call the service with the right parameters. So here I'm using the service call to do a call to a specific number. Very nice. So this command will send messages to the service. Of course, here I'm running as root. That's why I can do it. And we have of course the application on top of everything. And if we compare to a Linux system, the applications are very different, right? By default, we develop Java or Kotlin. Of course, we could use other tools with bindings for other languages, but by default, Java code or Kotlin are both the full languages for Android. And they are packaged with a file format called ATK with the codes, resources, and everything else. And we installed it. We could install it using a marketplace, the Google Play or manually if we want. The applications in Android are composed of different components. I don't have time to go over those components, but yeah, it's a little bit different from Linux Graph Co. application, for example using GTK or QT. And the applications communicate over protocol that Google created called Intent. I will talk a little bit about it, but unfortunately, I don't have time to talk about it. But Google worries a lot about fragmentation, especially because they want to update frequently Android, but they can because from the released search code to the final version of Android user, we have a lot of changes made by the silicon provider and that's a problem. So they created a lot of projects like Treble, Project Mainline, the kernel before we imaged that they created a lot of projects to try to improve the situation. That's why sometimes the architecture of the operating system is a little bit complex, right? Because they are trying to solve this kind of complex problems. So to conclude my presentation I would say what is the similarity between an Android system and a Linux system? The Linux kernel. Almost everything else is different, right? From the way you manage the search code, the way you build the components of the search code, the distribution, the GMOs, the common line tools, the libraries, the way the components communicate using the binder, so almost everything else is different. So should we say that Android is a Linux distribution? I will not say that. I will basically say that Android is an operating system based on the Linux kernel. Very nice, some final references if you want to check out basically the main documentation is search.android.com You can have a look at the search code, right? And of course, there are some good presentations from cutting on YouTube if you want to check out that I would say are the main references to study and follow Android. I hope you guys enjoyed this presentation. Those are my contacts. Now I'm going to open this session for questions and answers if you have time Thank you all for your time. See you in the next talk. Bye-bye.