The legend about AIDL. Part 1. The roots

Vladislav Puryev
8 min readJan 16, 2021

Hello everybody.

I would like to tell you one story about very ancient and not popular character of Android system. Not popular for developers, as they suppose. This is Android Interface Definition Language.

In this article I want to tell you about the origin of AIDL, about the base concept — IDL. Let’s get started.

WARNING! This article contains theoretical information only. The code examples, internals and actual technical details from Android system will be provided in the next articles.

This series of articles consist of three parts:

  1. The legend about AIDL. Part 1. The roots (you are here)
  2. The legend about AIDL. Part 2. In Action
  3. The legend about AIDL. Part 3. The crucial ingredient

What is IDL

AIDL means Android Interface Definition Language. But before get to know more about platform specific mechanism, it is useful to learn something about its theoretical basis. Let’s forget about Android for a while and try to understand what Interface Definition Language is. Well, there are not too many official definitions for this concept, but I like next one (source):

Interface definition language — is a language that describes the interface between client and server process in a distributed system.

I suppose it is not very clear. Let’s break it down.

Independent Communication

What is one of the main features of distributed systems? They can interact (even must interact) with many processes. Process is a single complicated concept, which is beyond of this article. Just for now, you should know (if you are not familiar with it) next thing: process is an program (application) at runtime. All of it is quite rough, but enough.

More important for distributed systems, that applications can be developed with different programming languages and technologies. And they can be located on different computers. Or they can be on one computer (device), but on distinct and independent virtual machines.

Anyway user must have access to programs and resources that distributed system can give him. It means that applications should have the way to communicate with each other by convenient and universal approach. Therefore RPC (Remote Procedure Call) concept was invented. It is an approach, which allows client application to invoke server application functions without any knowledge about server-side implementation.

Remote Procedure Call is the synchronous language-level transfer of control between programs in disjoint address spaces whose primary communication medium is a narrow channel.

What is so good in this concept? Client side does not care about any implementation’s details of server side.

Did you notice word “channel”? It is something that connects two sides. But one of the main advantages of RPC is that these sides don’t know about it. Client just calls functions of server side program, that returns the value or not.

It is like your actions, when you are trying to order a food. You just make a call from your smartphone and you don’t care about special technologies, which allow you to call, allow sending sound information, synchronize it and so on. And, of course, it does not matter for you, how your order is processed. You just make a call, speak your wishes and that is it. No worries about how it works at all steps.

But RPC is just an approach. IDL is a mechanism, which implements this approach for communication between applications.

IDL usage on client side

In this case IDL seems as simple interface in programming languages, having only implementations, which it hides. It looks like that both applications are on one machine. And for client side it really works almost in this way, as local usage. In this case it does not look like a solution for interactions between client and server programs. Therefore the scheme above is not enough to make right communication between different processes, in disjoint address spaces. But it is fair for client usage.

It is one of the main goals of Remote Procedure Call. This approach must provide the way of communications between programs, where remote calls look and behave exactly the same as local procedure (source). Using interface instead of implementations is significant part of this solution.

What if client program, that written on Kotlin, passes the integer value to server program interface (that is implemented on C++) and can get string value as response? It means that both programs work only with their languages data types. You cannot write programs implementations with IDL, it is just for definition of something like communication protocol. In this case, IDL becomes something universal and independent of any programming technologies. But how one type can be transformed into the same, but from another programming language?

Additional help

Let’s start from that IDL is not only an interface, which you are familiar with in different programming languages. It also includes special Compilers. They are using for generation of extra code. Okay, and what do they generate?

Well, let’s move step by step. Suppose that you have client application. You know, that you need to use some function from another program (perform remote procedure call). You know only one thing about this program — it is an implementation of some interface, which you have access to. It means that in your code it is only possible to call function, pass parameters and get result Also may be getting some exception.

Now compilers start work. In this case, when you call a function — you don’t do this straightforward from remote application. Not bad, heh? You call a function of IDL compiler generated class, which is an implementation of an IDL interface. It also does not call remote application. What? That is right. Instead of this, method in generated class just passes the data with input parameters to narrow channel (it will be described later).

Further the same process is executing on the other side. Remote program gets the call, perform its work and return the value. But it returns not to caller directly. Instead of this, IDL generated class for server side is getting the result from server program and this value is passing to channel. On other side client’s generated code gets a returning value from this channel. And only after that client program gets result. This not very clear interaction is calling Transfer.

Working of compilers during RPC

Well, nice, but how is it possible to use language-dependent types? The solution is implemented by compilers again, but they using approach, that is calling Source-level stubs (source). The main idea, that code, performing the Transfer procedures between programs, is generated by compilers for both sides — one for client and one for server.

In this case each IDL object is using appropriate programming language. It means, that there is no problem for sides to use these “stub routines”, because they are implemented on the same language. And now you can understand better the statements above. The call from client goes to stub of server, and the server side return is performing to client stub. Only stubs communicate with applications directly. Thus these two components “hide” the fact that call of procedure (function/method) is not local.

Whole working of IDL

What is so good in this approach? You don’t need change any line of code on any side. As developer, you can’t see difference between local or remote call. You do the same job as if functions are located at the same program. All necessary work will be done by compilers, only interface matters to you.

Connection

I think that there is one more question is remaining. How is remote procedure call performed, if both applications are on different machines?

Well, let’s remember about “narrow channel”, mentioned above. It is a way, how data from client can be transmitted to server and vice-versa. It does not matter, how channel works and how it is implemented.

But, there is one strict rule about narrow channel, which RPC can’t ignore. Data must be transmitted through this channel in form, that channel can use. It is logical, that your network (for example) can’t get char arguments from every language. Therefore input parameters and return value must be converted to a form, that channel can take. This process is calling marshalling. There are several definitions of this term, let me construct my own.

Marshalling—the process of packaging data of one program into message, that is suitable for sending to program, located in another address space.

Of course, after data was transformed to one form and passed through channel, it must be transformed inverse on other side (retrieving arguments from message). The reverse process is calling unmarshalling. And not exactly the same object is passing through the channel, but its copy. It is one more thing, which helps to pass programming language-independent data to remote application. In this case, the channel is something that can connect programs with different addresses.

Finally, the common work using IDL consists of next steps:

  1. Client program calls method of interface (IDL).
  2. The method of client stub is executing inside.
  3. Client stub performs marshalling of the data, that was passed as the parameters of method to the message and passes it to channel.
  4. The data is passing to server stub from channel.
  5. Server stub retrieves data and performs unmarshalling of it (convert to form, that is necessary for server application).
  6. Server stub calls server method (remote procedure).
  7. Server method computes result and makes return or exception to server stub. Note, that void is normal return.
  8. Server stub performs marshalling of the result and passes it to channel.
  9. Client stub gets message from channel, retrieves data and performs unmarshalling of it.
  10. Client stub passes result to client side application.

Conclusion

This article describes just common principles of RPC and IDL in very shortened form. Specific implementations and mechanics are depending on specific systems.

But the main goal was to show you, that AIDL is based on quite “ancient” mechanism (it was invented in start of 1980s), that was developed as the solution of different problems. The main advantage of this is that developers of different applications can don’t worry about “other side” details. They just know, what methods are accessible and what parameters they can pass (and there is no difference either this method is local or not). If client or server side code will be changed, it wouldn’t lead changing of another application code. Furthermore, this mechanism allows developing both programs on different programming languages.

Well, I think, that it is quite enough to show, that IDL has real goals and it accomplishes them.

There is no any line of code that is why it is quite difficult to understand all details. For them, please welcome to the second part and third one. Thank you for your time. Hope, that it was useful.

Stay well and have a good mood. See you again.

Useful links

Thank to my brother, who reviewed this article first and helped me to create it.

Special thanks to Kirill Rozov for review of this article and valuable advice.

--

--