Android Treble Architecture: Part 3 - Changes for Treble[Binder & ServiceManager]
Introduction.
We saw in the earlier
tutorial an overview of the changes done as part of Project Treble. We also
understood how decoupling the Vendor HAL implementation from the core system
framework avoids re-working on the HAL.
In this tutorial let us
start looking at the core differences in detail. During the analysis we will
also learn the core components and the major how to do’s for being Treble
compliant.
Binder Changes.
For Treble to work and
decouple the HAL’s from the core framework, A lot of changes were done to the existing
binder infrastructure. Some of these are.
1. support multiple /dev instances.
2. Support multiple selinux contexts for these
owners of the binders dev.
The binder.devices
parameter is a comma-separated list of strings that specifies the names of the
binder device nodes that will be created. Each binder device has its own
context manager, and is therefore logically separated from the other devices.
The 3 new /dev/
interfaces in binder now decouple the need to have the HAL in the same process
context.
Prior to OREO there was only one service manager which would use /dev/binder and talk to the HAL’s,
However Android now has various service managers for
1. Framework->Framework
2. Framework->Vendor
3. Vendor->Vendor communications.
Binder
communication changes.
The
Treble architecture above shows just how important is the Binder communication
infrastructure.
All
the cross process communications are achieved using the binder interface. This
might look transparent to the developer and it feels like a local function call.
However, a lot goes in achieving this transparency.
To
implement the decoupling of the framework and the HAL infrastructure binders
plays a very important role. The binder communication is still used between
Framework and HAL, and the communication interface is defined by HIDL[We will
discuss Hardware Interface Description Language aka HIDL in details later].
In
Treble, multiple binder domains have been introduced and multiple binder
devices have been added. The core implementation principle of the binder driver
has not changed however.
Since
the Android framework and HAL now use Binder to communicate with each other.
This communication greatly increases the Binder traffic.
To
effectively split the Binder traffic between the framework (device-independent)
and the vendor (device-specific) code, Android O introduces the concept of
"Binder context".
Each
Binder context has its own device node and context (service) manager. You can
only access it through the device node to which the context manager belongs,
and when a Binder node is passed through a specific context, the context
manager can only be accessed from the same context by another process, ensuring
that these domains are completely isolated from each other.
For
example, In order to display /dev/vndbinder, we need to make sure the kernel
configuration CONFIG_ANDROID_BINDER_DEVICES is set to "binder, hwbinder,
vndbinder".
From
the following link for kernel 4.4
All
the nodes from the configuration gets passed as the parameters.
All
the nodes get created and initialized.
We
can see from above all the 3 nodes, /dev/binder, /dev/hwbinder &
/dev/vndbinder are initialized and a context gets associated with them.
Since
both vndbinder and binder use the libbinder.so librarywe need to pass the node
to be used in this case.
For
an Example: We can see the mediacodecservice uses the vndbinder
For
more details on the changes done in binder driver for supporting HIDL or Treble
please see the following.
ServiceManager Changes [Extensions].
To
achieve the proper decoupling of HAL and framework, Treble also extends the
existing ServiceManager framework by adding two more such managers.
So
in total we now have 3 different ServiceManagers which uses these different
binder nodes for IPC and achieve process decoupling. They are the following
1. ServiceManager:
2. HwServiceManager:
3. VndServiceManager:
As
seen above since we have 3 nodes in the binder interface, The 3 servicemanagers
use these for all IPC.
Let
us see these managers and their interactions with the binder architecture.
ServiceManager uses /dev/binder.
HwServiceManager uses /dev/hwbinder.
vndServiceManager uses /dev/vndbinder.
Since
both vndbinder and binder use the libbinder.so library, when opening the binder
device, we need to call:
ProcessState::initWithDriver("/dev/vndbinder");
to specify which open binder device to open.
Let
us see these Managers one by one.
ServiceManager.
The
ServiceManager has not gone too many changes apart from the fact that now it
uses Android.bp [Read blueprint- Android’s new way of building things using
soong and the GO language].
However
the most important point to note is that the same code gets duplicated as
vndservicemanager based on the VENDORSERVICEMANAGER compilation flag [We will
come to vndservicemanager later below].
The
code is located at frameworks/native/cmds/servicemanager/
Let
us have a look at the Makefile, servicemanager.rc is used to start the
servicemanager during startup.
Note,
we have already covered the ServiceManager startup and registration of a
service code details in an earlier tutorial. Please see this link for a revisit.
Vndservicemanager.
In
the earlier versions of Android, All services were registered using
servicemanager [as shown above], They were obtained by a typical call to “sm->getService(“name
of the service”)” by the processes needing their services.
Starting
Android O, The servicemanager is now only dedicated to frameworks and
application processes which are no longer accessible to vendor processes.
However,
vendor services can now use vndservicemanager, a new instance of servicemanager
that uses /dev/vndbinder instead of /dev/binder.
The
vendor process communicates with vndservicemanager without changes in the core
concepts of service_manager, The only exception being the new binder node.
Servicemanager
and vndservicemanager both use the same code compiled from service_manager.c.
The main difference been the following.
1. Macro definition of VENDORSERVICEMANAGER
to indicate the code for vndservicemanager gets compiled.
2. Use of /dev/vndbinder as
an extra argument to the vndservicemanager executable.
3. Use of a separate
selinux handle for labelling [Quite understandable given that the processes
using them are different]
The
Makefile which sets the MACRO and the related .rc file.
The
vndservicemanager.rc which adds extra parameter of /dev/vndbinder for use.
One
important point of difference between the vndservicemanager and servicemanager
is the use of different sepolicy context[Apart from the binder node difference].
These
differences can be easily found by comparing the contents of following files.
vs
The
salient one’s being.
1.
The selinux policy files used by servicemanager and
vndservicemanager are different
a.
Servicemanager uses /system/etc/selinux/plat_service_contexts
b.
Vndservicemanager uses /vendor/etc/selinux/vndservice_contexts
2.
The labelling of the resources are different eg:
a.
Servicemanager uses service list
b.
Vndservicemanager uses vndservice list
Let
us see some other ones as well.
HwServiceManager.
Probably
the most important and differentiating component in the servicemanager list
would be the HwServiceManager.
Since
It uses the HIDL [Hardware Interface Description Language aka AIDL for the HAL]
a lot of changes are required and hence it cannot re-use the servicemanager
source unlike the vndservicemanager.
The
code for the HwServicemanager is in system/hwservicemanager [ https://android.googlesource.com/platform/system/hwservicemanager/+/android-8.1.0_r9
].
The
HwserviceManager gets started during boot through the hwservicemanager.rc file.
Let
us look at the Android.bp file for the hwservicemanager.
Also,
see that somewhere above we saw that both servicemanager &
vndservicemanager both use libbinder [With a difference in the node], However
hwservicemanager uses libhwbinder.
The
following table shows the main contents of both the libraries. It is important
to see the files which are same/similar across.
libhwbinder
location: system/libhwbinder/ |
libbinder
location: frameworks/native/libs/binder/ |
Android.bp
|
aidl
|
Binder.cpp
|
Android.bp
|
BpHwBinder.cpp
|
AppOpsManager.cpp
|
BufferedTextOutput.cpp
|
Binder.cpp
|
.clang-format
|
BpBinder.cpp
|
Debug.cpp
|
BufferedTextOutput.cpp
|
IInterface.cpp
|
Debug.cpp
|
include/
|
IActivityManager.cpp
|
IPCThreadState.cpp
|
IAppOpsCallback.cpp
|
IAppOpsService.cpp
|
IMediaResourceMonitor.cpp
|
IBatteryStats.cpp
|
IMemory.cpp
|
IInterface.cpp
|
include
|
Parcel.cpp
|
IPCThreadState.cpp
|
PREUPLOAD.cfg
|
IPermissionController.cpp
|
ProcessState.cpp
|
IpPrefix.cpp
|
Static.cpp
|
IProcessInfoService.cpp
|
TextOutput.cpp
|
IResultReceiver.cpp
|
vts/
|
IServiceManager.cpp
|
IShellCallback.cpp
|
|
MemoryBase.cpp
|
|
MemoryDealer.cpp
|
|
MemoryHeapBase.cpp
|
|
Parcel.cpp
|
|
PermissionCache.cpp
|
|
PersistableBundle.cpp
|
|
ProcessInfoService.cpp
|
|
ProcessState.cpp
|
|
Static.cpp
|
|
Status.cpp
|
|
tests
|
|
TextOutput.cpp
|
|
Value.cpp
|
We
will get into more into the binder library details at a later stage.
We
now have fair idea on the key differences between the version of Android with
and without the Treble feature.
We
will continue our analysis in the next tutorials.
I have learned a lot from this post which will help me in future. Home Design Makeover Cheats
ReplyDeleteToo good article,keep sharing more articles with us
ReplyDeleteandroid online training
kartal bosch klima servisi
ReplyDeletependik arçelik klima servisi
çekmeköy vestel klima servisi
ataşehir vestel klima servisi
çekmeköy bosch klima servisi
ataşehir bosch klima servisi
çekmeköy arçelik klima servisi
ataşehir arçelik klima servisi
maltepe samsung klima servisi