Android Binder Framework

Budhdi Sharma
AndroidPub
Published in
5 min readDec 11, 2019

--

In the Linux OS, there are several techniques to achieve IPC (Inter-process communication) like files, sockets, signals, pipes, message queues, semaphores, shared memory, etc. However, Android’s modified Linux kernel comes with a binder framework which enables an RPC (remote procedure call) mechanism between the client and server processes, where the client process can execute remote methods in the server process as if they were executed locally. So data can be passed to the remote method calls and results can be returned to the client calling thread. It appears as if the thread from the client process jumps into another (remote) process and starts executing in there (known as Thread Migration).

What is Binder?

An IPC/component system for developing object-oriented OS services

  • A kernel driver to facilitate inter-process communication.
  • Lightweight RPC (Remote Procedure Communication) mechanism.
  • Per-process thread pool for processing requests.
  • Synchronous communication b/w processes
  • Not yet another object-oriented kernel.
  • Instead, an object-oriented operating system environment that works on traditional kernels, like Linux!
  • Essential to Android!
  • Comes from OpenBinder:-

Started at Be, Inc. as a key part of the “next generation BeOS” (~ 2001), Acquired by PalmSource, First implementation used in Palm Cobalt (micro-kernel based OS),Palm switched to Linux, so Binder ported to Linux, open-sourced (~ 2005) ,Google hired Dianne Hackborn, a key OpenBinder engineer, to join the Android team Used as-is for the initial bring-up of Android, but then completely rewritten (~ 2008) OpenBinder no longer maintained — long live Binder!

IPC

  • Inter-process communication (IPC) is a framework for the exchange of signals and data across multiple processes.
  • Used for message passing, synchronization, shared memory, and remote procedure calls (RPC).
  • Enables information sharing, computational speedup, modularity, convenience, privilege separation, data isolation, stability( Each process has its own (sandboxed) address space, typically running under a unique system ID)
  • Many IPC options:-

Files (including memory mapped)

Signals Sockets (UNIX domain, TCP/IP)

Pipes (including named pipes)

Semaphores

Shared memory

Message passing (including queues, message bus)

Intents, ContentProviders, Messenger

Binder!

Binder Terminology

The Binder framework uses its own terminology to name facilities and components.

Binder This term is used ambiguously. The Binder refers to the overall Binder architecture, whereas a Binder refers to a particular implementation of a Binder interface.

Binder Object is an instance of a class that implements the Binder interface. A Binder object can implement multiple Binders.

Binder Protocol The Binder middleware uses a very low-level protocol to communicate with the driver.

IBinder Interface A Binder interface is a well-defined set of methods, properties, and events that a Binder can implement. It is usually described by the AIDL1 language.

Binder Token A numeric value that uniquely identifies a Binder.

Why Binder?

  • Android apps and system services run in separate processes for security, stability, and memory management reasons, but they need to communicate and share data! Security: each process is sandboxed and run under a distinct system identity, Stability: if a process misbehaves (e.g. crashes), it does not affect any other processes Memory management: “unneeded” processes are removed to free resources (mainly memory) for new ones, In fact, a single Android app can have its components run in separate processes.
  • IPC to the rescue But we need to avoid the overhead of traditional IPC and avoid denial of service issues.
  • Android’s libc (a.k.a. bionic) does not support System V IPCs, No SysV semaphores, shared memory segments, message queues, etc. System V IPC is prone to kernel resource leakage when a process “forgets” to release shared IPC resources upon termination Buggy, malicious code, or a well-behaved app that is low-memory.
  • Binder to the rescue! Its built-in reference-counting of “object” references plus death-notification mechanism make it suitable for “hostile” environments (where low memory killer roams) When a binder service is no longer referenced by any clients, its owner is automatically notified that it can dispose of it.
  • Many other features: “Thread migration” — like programming model: Automatic management of thread-pools Methods on remote objects can be invoked as if they were local — the thread appears to “jump” to the other process Synchronous and asynchronous (oneway) invocation model Identifying senders to receivers (via UID/PID) — important for security reasons Unique object-mapping across process boundaries A reference to a remote object can be passed to yet another process and can be used as an identifying token Ability to send file descriptors across process boundaries Simple Android Interface Definition Language (AIDL) Built-in support for marshaling many common data-types Simplified transaction invocation model via auto-generated proxies and stubs (Java-only) Recursion across processes — i.e. behaves the same as recursion semantics when calling methods on local objects Local execution mode (no IPC/data marshaling) if the client and the service happen to be in the same process.
  • But: No support for RPC (local-only) Client-service message-based communication — not well-suited for streaming Not defined by POSIX or any other standard.
  • Most apps and core system services depend on Binder Most app component life-cycle call-backs (e.g. onResume(), onDestory(), etc.) are invoked by ActivityManagerService via binder Turn off binder, and the entire system grinds to a halt (no display, no audio, no input, no sensors, …) Unix domain sockets used in some cases (e.g. RILD).

Binder Communication Model

  • As far as the client is concerned, it just wants to use the service:
  • While processes cannot directly invoke operations (or read/write data) on other processes, the kernel can, so they make use of the Binder driver:

Since the service may get concurrent requests from multiple clients, it needs to protect (synchronize access to) its mutable state.

The Binder framework communication is a client-server model. Each client initiates communication and waits for a response from the server. Each client would have a proxy object for the client-side communication. The server side constitutes a pool of worker threads. The server shall spawn a new thread for each new Binder request from the client. The bridge between the client and the server process is the binder driver. The Binder driver is a character device that is part of kernel space. This module ensures the client reaches the appropriate destination across process boundaries.

If you want to know more about it or any query, please leave a comment here!

Thanks for the Support!

--

--

Budhdi Sharma
AndroidPub

As an AOSP developer, I specialize in creating robust framework and system applications that seamlessly integrate with embedded systems on various SOCs