SlideShare a Scribd company logo
Android Services Internals
by

Somenath Mukhopadhyay
som.mukhopadhyay@gmail.com
Have you ever wondered how an app gets an handle to the system services like POWER
MANAGER or ACTIVITY MANAGER or LOCATION MANAGER and several others like
these. To know that i dug into the source code of Android and found out how this is done
internally.
The investigation detailed below will work as an hand­holder for an Android internal
learners.
So let me start from the application side’s java code.
At the application side we have to call the function getService and pass the ID of the
system service (say POWER_SERVCE) to get an handle to the service.
Here is the code for getService defined in
/frameworks/base/core/java/android/os/ServiceManager.java
/**
44     * Returns a reference to a service with the given name.
45     *
46     * @param name the name of the service to get
47     * @return a reference to the service, or <code>null</code> if the service doesn't
exist
48     */
49    public static IBinder getService(String name) {
50        try {
51            IBinder service = sCache.get(name);
52            if (service != null) {
53                return service;
54            } else {
55                return getIServiceManager().getService(name);
56            }
57        } catch (RemoteException e) {
58            Log.e(TAG, "error in getService", e);
59        }
60        return null;
61    }
Suppose we don’t have the service in the cache. Hence we need to concentrate on the line
55
return getIServiceManager().getService(name);
This call actually gets an handle to the service manager and asks it to return a reference of
the service whose name we have passed as a parameter.

Now let us see how the getIServiceManager() function returns a handle to the
ServiceManager.
Here is the code of getIserviceManager() from
/frameworks/base/core/java/android/os/ServiceManager.java
private static IServiceManager getIServiceManager() {
34        if (sServiceManager != null) {
35            return sServiceManager;
36        }
37
38        // Find the service manager
39        sServiceManager =
ServiceManagerNative.asInterface(BinderInternal.getContextObject());
40        return sServiceManager;
41    }
Look at the line 39. Here we get an handle to the BpServiceManager. The reason is
because after the systemserver start servicemanager(call main in service_manager.c), the
servicemanager will register itself as a context_manager of binder by ioctl(bs­>fd,
BINDER_SET_CONTEXT_MGR, 0) through the function
int binder_become_context_manager(struct binder_state *bs)
{
return ioctl(bs­>fd, BINDER_SET_CONTEXT_MGR, 0);
}

The ServicemanagerNative.asInterface() looks like the following:
/**
28     * Cast a Binder object into a service manager interface, generating
29     * a proxy if needed.
30     */
31    static public IServiceManager asInterface(IBinder obj)
32    {
33        if (obj == null) {
34            return null;
35        }
36        IServiceManager in =
37            (IServiceManager)obj.queryLocalInterface(descriptor);
38        if (in != null) {
39            return in;
40        }
41
42        return new ServiceManagerProxy(obj);
43    }

So basically we are getting a handle to the native servicemanager.
This asInterface function is actually buried inside the two macros
DECLARE_META_INTERFACE(ServiceManager) and
IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager");
defined in IserviceManager.h and IServiceManager.cpp respectively.
Lets delve into the two macros defined in /frameworks/base/include/binder/IInterface.h
DECLARE_META_INTERFACE(ServiceManager) macro.
Its defined as
// ­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­
73
74#define DECLARE_META_INTERFACE(INTERFACE)                               
75    static const android::String16 descriptor;                          
76    static android::sp<I##INTERFACE> asInterface(                       
77            const android::sp<android::IBinder>& obj);                  
78    virtual const android::String16& getInterfaceDescriptor() const;    
79    I##INTERFACE();                                                     
80    virtual ~I##INTERFACE();                                            
And the IMPLEMENT_META_INTERFACE(ServiceManager,
"android.os.IServiceManager");
has been defined as follows:
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME)                       
84    const android::String16 I##INTERFACE::descriptor(NAME);             
85    const android::String16&                                            
86            I##INTERFACE::getInterfaceDescriptor() const {              
87        return I##INTERFACE::descriptor;                                
88    }                                                                   
89    android::sp<I##INTERFACE> I##INTERFACE::asInterface(                
90            const android::sp<android::IBinder>& obj)                   
91    {                                                                   
92        android::sp<I##INTERFACE> intr;                                 
93        if (obj != NULL) {                                              
94            intr = static_cast<I##INTERFACE*>(                          
95                obj­>queryLocalInterface(                               
96                        I##INTERFACE::descriptor).get());               
97            if (intr == NULL) {                                         
98                intr = new Bp##INTERFACE(obj);                          
99            }                                                           
100        }                                                               
101        return intr;                                                    
102    }                                                                   
103    I##INTERFACE::I##INTERFACE() { }                                    
104    I##INTERFACE::~I##INTERFACE() { }
So if we replace expand these two macros in IServiceManager.h & IServiceManager.cpp
file with the appropriate replacement parameters they look like the following:
1. class IServiceManager : public IInterface
{
public:
   static const android::String16 descriptor;
2.     static android::sp<IServiceManager> asInterface( const
android::sp<android::IBinder>& obj);
3.     virtual const android::String16& getInterfaceDescriptor() const;
4.     IServicemanager();
5.     virtual ~IServiceManager();
…......
….....
…...
…..
And in
IServiceManager.cpp
1.
2.     const android::String16
IServiceManager::descriptor("android.os.IServiceManager”);
3.     const android::String16&
4.            IServiceManager::getInterfaceDescriptor() const {
5.         return  IServiceManager::descriptor;
6.     }
7.     android::sp<IServiceManager> IServiceManager::asInterface(
8.             const android::sp<android::IBinder>& obj)
9.     {
10.         android::sp< IServiceManager> intr;
11.         if (obj != NULL) {
12.             intr = static_cast<IServiceManager*>(
13.                 obj­>queryLocalInterface(
14.                         IServiceManager::descriptor).get());
15.             if (intr == NULL) {
16.                 intr = new BpServiceManager(obj);
17.             }
18.         }
19.         return intr;
20.     }
21.     IServiceManager::IServiceManager() { }
22.     IServiceManager::~IIServiceManager { }
If you look at line 15, you will get how we get an handle to the BpServiceManager.
now once we get the reference of the Service Manager, we next call
public IBinder getService(String name) throws RemoteException {
116        Parcel data = Parcel.obtain();
117        Parcel reply = Parcel.obtain();
118        data.writeInterfaceToken(IServiceManager.descriptor);
119        data.writeString(name);
120        mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
121        IBinder binder = reply.readStrongBinder();
122        reply.recycle();
123        data.recycle();
124        return binder;
125    }

from  ServiceManagerNative.java. in this function we pass the service that we are looking
for.
It returns the reference to the needed service through the function getService.
The getService function from /frameworks/base/libs/binder/IServiceManager.cpp
looks like the following:
  virtual sp<IBinder> getService(const String16& name) const
134    {
135        unsigned n;
136        for (n = 0; n < 5; n++){
137            sp<IBinder> svc = checkService(name);
138            if (svc != NULL) return svc;
139            LOGI("Waiting for service %s...n", String8(name).string());
140            sleep(1);
141        }
142        return NULL;
143
And the above checkService(name) looks like the following:
1. virtual sp<IBinder> checkService( const String16& name) const
2.  
3.     {
4.         Parcel data, reply;
5.  
6.         data.writeInterfaceToken(IServiceManager::getInterfaceDescriptor());
7.  
8.         data.writeString16(name);
9.  
10.         remote()­>transact(CHECK_SERVICE_TRANSACTION, data, &reply);
11.  
12.         return reply.readStrongBinder();
13.  
14.     }
So it actually calls a remote service and pass CHECK_SERVICE_TRANSACTION code
(its an enum value of 2) to it.
This remote service is actually implemented in
frameworks/base/cmds/servicemanager/service_manager.c
and its onTransact looks like the following.
switch(txn­>code) {
   case SVC_MGR_GET_SERVICE:
   case SVC_MGR_CHECK_SERVICE:
a.         s = bio_get_string16(msg, &len);
b.         ptr = do_find_service(bs, s, len);
c.         if (!ptr)
d.             break;
e.         bio_put_ref(reply, ptr);
f.

        return 0;

Hence we end up calling the function named do_find_service which gets a reference to the
service and returns it back.
The do_find_service from the same file looks as follows:
void *do_find_service(struct binder_state *bs, uint16_t *s, unsigned len)
{
    struct svcinfo *si;
    si = find_svc(s, len);

//    ALOGI("check_service('%s') ptr = %pn", str8(s), si ? si­>ptr : 0);
    if (si && si­>ptr) {
        return si­>ptr;
    } else {
        return 0;
    }
}

find_svc looks as follows:
struct svcinfo *find_svc(uint16_t *s16, unsigned len)
{
    struct svcinfo *si;

    for (si = svclist; si; si = si­>next) {
        if ((len == si­>len) &&
            !memcmp(s16, si­>name, len * sizeof(uint16_t))) {
            return si;
        }
    }
    return 0;
}
As it becomes clear that it traverses through the svclist and returns the the service we are
looking for.
Hope it helps the Android learners to know about the internal of Android services.

More Related Content

PPTX
Spring FrameWork Tutorials Java Language
ODT
Spring IOC advantages and developing spring application sample
PPTX
Dependency Injection або Don’t call me, I’ll call you
PDF
Angular Dependency Injection
PPTX
Request Validation In Spring Rest-Part2
PPTX
Spring REST Request Validation
ODP
CDI @javaonehyderabad
PDF
Vaadin with Java EE 7
Spring FrameWork Tutorials Java Language
Spring IOC advantages and developing spring application sample
Dependency Injection або Don’t call me, I’ll call you
Angular Dependency Injection
Request Validation In Spring Rest-Part2
Spring REST Request Validation
CDI @javaonehyderabad
Vaadin with Java EE 7

More from Somenath Mukhopadhyay (20)

PDF
Significance of private inheritance in C++...
PDF
Arranging the words of a text lexicographically trie
PDF
Generic asynchronous HTTP utility for android
PDF
Copy on write
PDF
Java concurrency model - The Future Task
PDF
Memory layout in C++ vis a-vis polymorphism and padding bits
PDF
Developing an Android REST client to determine POI using asynctask and integr...
PDF
Observer pattern
PDF
Uml training
PDF
How to create your own background for google docs
PDF
The Designing of a Software System from scratch with the help of OOAD & UML -...
PDF
Structural Relationship between Content Resolver and Content Provider of Andr...
PDF
Flow of events during Media Player creation in Android
PDF
Implementation of a state machine for a longrunning background task in androi...
PDF
Tackling circular dependency in Java
PDF
Implementation of composite design pattern in android view and widgets
PDF
Exception Handling in the C++ Constructor
PDF
Active object of Symbian in the lights of client server architecture
PDF
Android Asynctask Internals vis-a-vis half-sync half-async design pattern
PDF
Composite Pattern
Significance of private inheritance in C++...
Arranging the words of a text lexicographically trie
Generic asynchronous HTTP utility for android
Copy on write
Java concurrency model - The Future Task
Memory layout in C++ vis a-vis polymorphism and padding bits
Developing an Android REST client to determine POI using asynctask and integr...
Observer pattern
Uml training
How to create your own background for google docs
The Designing of a Software System from scratch with the help of OOAD & UML -...
Structural Relationship between Content Resolver and Content Provider of Andr...
Flow of events during Media Player creation in Android
Implementation of a state machine for a longrunning background task in androi...
Tackling circular dependency in Java
Implementation of composite design pattern in android view and widgets
Exception Handling in the C++ Constructor
Active object of Symbian in the lights of client server architecture
Android Asynctask Internals vis-a-vis half-sync half-async design pattern
Composite Pattern
Ad

Recently uploaded (20)

DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PDF
cuic standard and advanced reporting.pdf
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Electronic commerce courselecture one. Pdf
PDF
Unlocking AI with Model Context Protocol (MCP)
PPTX
Big Data Technologies - Introduction.pptx
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
The AUB Centre for AI in Media Proposal.docx
Dropbox Q2 2025 Financial Results & Investor Presentation
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
cuic standard and advanced reporting.pdf
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
How UI/UX Design Impacts User Retention in Mobile Apps.pdf
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Electronic commerce courselecture one. Pdf
Unlocking AI with Model Context Protocol (MCP)
Big Data Technologies - Introduction.pptx
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Reach Out and Touch Someone: Haptics and Empathic Computing
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
20250228 LYD VKU AI Blended-Learning.pptx
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
Advanced methodologies resolving dimensionality complications for autism neur...
Ad

Android services internals