• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2007 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.os;
18 
19 import android.util.Log;
20 
21 import com.android.internal.os.BinderInternal;
22 
23 import java.util.HashMap;
24 import java.util.Map;
25 
26 /** @hide */
27 public final class ServiceManager {
28     private static final String TAG = "ServiceManager";
29 
30     private static IServiceManager sServiceManager;
31     private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();
32 
getIServiceManager()33     private static IServiceManager getIServiceManager() {
34         if (sServiceManager != null) {
35             return sServiceManager;
36         }
37 
38         // Find the service manager
39         sServiceManager = ServiceManagerNative
40                 .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
41         return sServiceManager;
42     }
43 
44     /**
45      * Returns a reference to a service with the given name.
46      *
47      * @param name the name of the service to get
48      * @return a reference to the service, or <code>null</code> if the service doesn't exist
49      */
getService(String name)50     public static IBinder getService(String name) {
51         try {
52             IBinder service = sCache.get(name);
53             if (service != null) {
54                 return service;
55             } else {
56                 return Binder.allowBlocking(getIServiceManager().getService(name));
57             }
58         } catch (RemoteException e) {
59             Log.e(TAG, "error in getService", e);
60         }
61         return null;
62     }
63 
64     /**
65      * Returns a reference to a service with the given name, or throws
66      * {@link NullPointerException} if none is found.
67      *
68      * @hide
69      */
getServiceOrThrow(String name)70     public static IBinder getServiceOrThrow(String name) throws ServiceNotFoundException {
71         final IBinder binder = getService(name);
72         if (binder != null) {
73             return binder;
74         } else {
75             throw new ServiceNotFoundException(name);
76         }
77     }
78 
79     /**
80      * Place a new @a service called @a name into the service
81      * manager.
82      *
83      * @param name the name of the new service
84      * @param service the service object
85      */
addService(String name, IBinder service)86     public static void addService(String name, IBinder service) {
87         try {
88             getIServiceManager().addService(name, service, false);
89         } catch (RemoteException e) {
90             Log.e(TAG, "error in addService", e);
91         }
92     }
93 
94     /**
95      * Place a new @a service called @a name into the service
96      * manager.
97      *
98      * @param name the name of the new service
99      * @param service the service object
100      * @param allowIsolated set to true to allow isolated sandboxed processes
101      * to access this service
102      */
addService(String name, IBinder service, boolean allowIsolated)103     public static void addService(String name, IBinder service, boolean allowIsolated) {
104         try {
105             getIServiceManager().addService(name, service, allowIsolated);
106         } catch (RemoteException e) {
107             Log.e(TAG, "error in addService", e);
108         }
109     }
110 
111     /**
112      * Retrieve an existing service called @a name from the
113      * service manager.  Non-blocking.
114      */
checkService(String name)115     public static IBinder checkService(String name) {
116         try {
117             IBinder service = sCache.get(name);
118             if (service != null) {
119                 return service;
120             } else {
121                 return Binder.allowBlocking(getIServiceManager().checkService(name));
122             }
123         } catch (RemoteException e) {
124             Log.e(TAG, "error in checkService", e);
125             return null;
126         }
127     }
128 
129     /**
130      * Return a list of all currently running services.
131      * @return an array of all currently running services, or <code>null</code> in
132      * case of an exception
133      */
listServices()134     public static String[] listServices() {
135         try {
136             return getIServiceManager().listServices();
137         } catch (RemoteException e) {
138             Log.e(TAG, "error in listServices", e);
139             return null;
140         }
141     }
142 
143     /**
144      * This is only intended to be called when the process is first being brought
145      * up and bound by the activity manager. There is only one thread in the process
146      * at that time, so no locking is done.
147      *
148      * @param cache the cache of service references
149      * @hide
150      */
initServiceCache(Map<String, IBinder> cache)151     public static void initServiceCache(Map<String, IBinder> cache) {
152         if (sCache.size() != 0) {
153             throw new IllegalStateException("setServiceCache may only be called once");
154         }
155         sCache.putAll(cache);
156     }
157 
158     /**
159      * Exception thrown when no service published for given name. This might be
160      * thrown early during boot before certain services have published
161      * themselves.
162      *
163      * @hide
164      */
165     public static class ServiceNotFoundException extends Exception {
ServiceNotFoundException(String name)166         public ServiceNotFoundException(String name) {
167             super("No service published for: " + name);
168         }
169     }
170 }
171