blob: bf9225a2780afcfcde2584aa7156cc62855efa3d [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
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
17package android.os;
18
Andrei Onea24ec3212019-03-15 17:35:05 +000019import android.annotation.UnsupportedAppUsage;
Robert Benea1901a5b2018-05-15 16:36:07 -070020import android.util.ArrayMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080021import android.util.Log;
22
Makoto Onuki49392d32018-04-11 13:51:02 -070023import com.android.internal.annotations.GuardedBy;
Jeff Sharkey49ca5292016-05-10 12:54:45 -060024import com.android.internal.os.BinderInternal;
Makoto Onuki49392d32018-04-11 13:51:02 -070025import com.android.internal.util.StatLogger;
Jeff Sharkey49ca5292016-05-10 12:54:45 -060026
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080027import java.util.Map;
28
29/** @hide */
30public final class ServiceManager {
31 private static final String TAG = "ServiceManager";
Makoto Onuki49392d32018-04-11 13:51:02 -070032 private static final Object sLock = new Object();
33
Andrei Onea24ec3212019-03-15 17:35:05 +000034 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080035 private static IServiceManager sServiceManager;
Makoto Onuki49392d32018-04-11 13:51:02 -070036
37 /**
38 * Cache for the "well known" services, such as WM and AM.
39 */
Andrei Onea24ec3212019-03-15 17:35:05 +000040 @UnsupportedAppUsage
Robert Benea1901a5b2018-05-15 16:36:07 -070041 private static Map<String, IBinder> sCache = new ArrayMap<String, IBinder>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042
Makoto Onuki49392d32018-04-11 13:51:02 -070043 /**
44 * We do the "slow log" at most once every this interval.
45 */
46 private static final int SLOW_LOG_INTERVAL_MS = 5000;
47
48 /**
49 * We do the "stats log" at most once every this interval.
50 */
51 private static final int STATS_LOG_INTERVAL_MS = 5000;
52
53 /**
54 * Threshold in uS for a "slow" call, used on core UIDs. We use a more relax value to
55 * avoid logspam.
56 */
57 private static final long GET_SERVICE_SLOW_THRESHOLD_US_CORE =
58 SystemProperties.getInt("debug.servicemanager.slow_call_core_ms", 10) * 1000;
59
60 /**
61 * Threshold in uS for a "slow" call, used on non-core UIDs. We use a more relax value to
62 * avoid logspam.
63 */
64 private static final long GET_SERVICE_SLOW_THRESHOLD_US_NON_CORE =
65 SystemProperties.getInt("debug.servicemanager.slow_call_ms", 50) * 1000;
66
67 /**
68 * We log stats logging ever this many getService() calls.
69 */
70 private static final int GET_SERVICE_LOG_EVERY_CALLS_CORE =
71 SystemProperties.getInt("debug.servicemanager.log_calls_core", 100);
72
73 /**
74 * We log stats logging ever this many getService() calls.
75 */
76 private static final int GET_SERVICE_LOG_EVERY_CALLS_NON_CORE =
77 SystemProperties.getInt("debug.servicemanager.log_calls", 200);
78
79 @GuardedBy("sLock")
80 private static int sGetServiceAccumulatedUs;
81
82 @GuardedBy("sLock")
83 private static int sGetServiceAccumulatedCallCount;
84
85 @GuardedBy("sLock")
86 private static long sLastStatsLogUptime;
87
88 @GuardedBy("sLock")
89 private static long sLastSlowLogUptime;
90
91 @GuardedBy("sLock")
92 private static long sLastSlowLogActualTime;
93
94 interface Stats {
95 int GET_SERVICE = 0;
96
97 int COUNT = GET_SERVICE + 1;
98 }
99
100 public static final StatLogger sStatLogger = new StatLogger(new String[] {
101 "getService()",
102 });
103
Andrei Onea24ec3212019-03-15 17:35:05 +0000104 @UnsupportedAppUsage
Artur Satayev751e5512019-11-15 19:12:49 +0000105 public ServiceManager() {
106 }
107
108 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 private static IServiceManager getIServiceManager() {
110 if (sServiceManager != null) {
111 return sServiceManager;
112 }
113
114 // Find the service manager
Jeff Sharkey0a17db12016-11-04 11:23:46 -0600115 sServiceManager = ServiceManagerNative
116 .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800117 return sServiceManager;
118 }
119
120 /**
121 * Returns a reference to a service with the given name.
Vishnu Nair05768192017-09-19 15:25:38 -0700122 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123 * @param name the name of the service to get
124 * @return a reference to the service, or <code>null</code> if the service doesn't exist
125 */
Andrei Onea24ec3212019-03-15 17:35:05 +0000126 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127 public static IBinder getService(String name) {
128 try {
129 IBinder service = sCache.get(name);
130 if (service != null) {
131 return service;
132 } else {
Makoto Onuki49392d32018-04-11 13:51:02 -0700133 return Binder.allowBlocking(rawGetService(name));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800134 }
135 } catch (RemoteException e) {
136 Log.e(TAG, "error in getService", e);
137 }
138 return null;
139 }
140
141 /**
Jeff Sharkey49ca5292016-05-10 12:54:45 -0600142 * Returns a reference to a service with the given name, or throws
143 * {@link NullPointerException} if none is found.
144 *
145 * @hide
146 */
147 public static IBinder getServiceOrThrow(String name) throws ServiceNotFoundException {
148 final IBinder binder = getService(name);
149 if (binder != null) {
150 return binder;
151 } else {
152 throw new ServiceNotFoundException(name);
153 }
154 }
155
156 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 * Place a new @a service called @a name into the service
158 * manager.
Vishnu Nair05768192017-09-19 15:25:38 -0700159 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 * @param name the name of the new service
161 * @param service the service object
162 */
Andrei Onea24ec3212019-03-15 17:35:05 +0000163 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800164 public static void addService(String name, IBinder service) {
Vishnu Nairdf6c6e72018-02-01 15:14:44 -0800165 addService(name, service, false, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
Dianne Hackborna573f6a2012-02-09 16:12:18 -0800166 }
167
168 /**
169 * Place a new @a service called @a name into the service
170 * manager.
Vishnu Nair05768192017-09-19 15:25:38 -0700171 *
Dianne Hackborna573f6a2012-02-09 16:12:18 -0800172 * @param name the name of the new service
173 * @param service the service object
174 * @param allowIsolated set to true to allow isolated sandboxed processes
175 * to access this service
176 */
Andrei Onea24ec3212019-03-15 17:35:05 +0000177 @UnsupportedAppUsage
Dianne Hackborna573f6a2012-02-09 16:12:18 -0800178 public static void addService(String name, IBinder service, boolean allowIsolated) {
Vishnu Nairdf6c6e72018-02-01 15:14:44 -0800179 addService(name, service, allowIsolated, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
Vishnu Nair05768192017-09-19 15:25:38 -0700180 }
181
182 /**
183 * Place a new @a service called @a name into the service
184 * manager.
185 *
186 * @param name the name of the new service
187 * @param service the service object
188 * @param allowIsolated set to true to allow isolated sandboxed processes
189 * @param dumpPriority supported dump priority levels as a bitmask
190 * to access this service
191 */
Andrei Onea24ec3212019-03-15 17:35:05 +0000192 @UnsupportedAppUsage
Vishnu Nair05768192017-09-19 15:25:38 -0700193 public static void addService(String name, IBinder service, boolean allowIsolated,
194 int dumpPriority) {
Dianne Hackborna573f6a2012-02-09 16:12:18 -0800195 try {
Vishnu Nair05768192017-09-19 15:25:38 -0700196 getIServiceManager().addService(name, service, allowIsolated, dumpPriority);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800197 } catch (RemoteException e) {
198 Log.e(TAG, "error in addService", e);
199 }
200 }
Vishnu Nair05768192017-09-19 15:25:38 -0700201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 /**
203 * Retrieve an existing service called @a name from the
204 * service manager. Non-blocking.
205 */
Andrei Onea24ec3212019-03-15 17:35:05 +0000206 @UnsupportedAppUsage
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800207 public static IBinder checkService(String name) {
208 try {
209 IBinder service = sCache.get(name);
210 if (service != null) {
211 return service;
212 } else {
Jeff Sharkey0a17db12016-11-04 11:23:46 -0600213 return Binder.allowBlocking(getIServiceManager().checkService(name));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800214 }
215 } catch (RemoteException e) {
216 Log.e(TAG, "error in checkService", e);
217 return null;
218 }
219 }
220
221 /**
222 * Return a list of all currently running services.
Umair Khan9ccebbf2016-01-06 19:47:20 +0530223 * @return an array of all currently running services, or <code>null</code> in
224 * case of an exception
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800225 */
Andrei Onea24ec3212019-03-15 17:35:05 +0000226 @UnsupportedAppUsage
Umair Khan9ccebbf2016-01-06 19:47:20 +0530227 public static String[] listServices() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800228 try {
Vishnu Naire78b01a2017-10-26 10:11:54 -0700229 return getIServiceManager().listServices(IServiceManager.DUMP_FLAG_PRIORITY_ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800230 } catch (RemoteException e) {
231 Log.e(TAG, "error in listServices", e);
232 return null;
233 }
234 }
235
236 /**
237 * This is only intended to be called when the process is first being brought
238 * up and bound by the activity manager. There is only one thread in the process
239 * at that time, so no locking is done.
Vishnu Nair05768192017-09-19 15:25:38 -0700240 *
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800241 * @param cache the cache of service references
242 * @hide
243 */
244 public static void initServiceCache(Map<String, IBinder> cache) {
Jeff Brown10e89712011-07-08 18:52:57 -0700245 if (sCache.size() != 0) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800246 throw new IllegalStateException("setServiceCache may only be called once");
247 }
248 sCache.putAll(cache);
249 }
Jeff Sharkey49ca5292016-05-10 12:54:45 -0600250
251 /**
252 * Exception thrown when no service published for given name. This might be
253 * thrown early during boot before certain services have published
254 * themselves.
255 *
256 * @hide
257 */
258 public static class ServiceNotFoundException extends Exception {
259 public ServiceNotFoundException(String name) {
260 super("No service published for: " + name);
261 }
262 }
Makoto Onuki49392d32018-04-11 13:51:02 -0700263
264 private static IBinder rawGetService(String name) throws RemoteException {
265 final long start = sStatLogger.getTime();
266
267 final IBinder binder = getIServiceManager().getService(name);
268
269 final int time = (int) sStatLogger.logDurationStat(Stats.GET_SERVICE, start);
270
271 final int myUid = Process.myUid();
272 final boolean isCore = UserHandle.isCore(myUid);
273
274 final long slowThreshold = isCore
275 ? GET_SERVICE_SLOW_THRESHOLD_US_CORE
276 : GET_SERVICE_SLOW_THRESHOLD_US_NON_CORE;
277
278 synchronized (sLock) {
279 sGetServiceAccumulatedUs += time;
280 sGetServiceAccumulatedCallCount++;
281
282 final long nowUptime = SystemClock.uptimeMillis();
283
284 // Was a slow call?
285 if (time >= slowThreshold) {
286 // We do a slow log:
287 // - At most once in every SLOW_LOG_INTERVAL_MS
288 // - OR it was slower than the previously logged slow call.
289 if ((nowUptime > (sLastSlowLogUptime + SLOW_LOG_INTERVAL_MS))
290 || (sLastSlowLogActualTime < time)) {
291 EventLogTags.writeServiceManagerSlow(time / 1000, name);
292
293 sLastSlowLogUptime = nowUptime;
294 sLastSlowLogActualTime = time;
295 }
296 }
297
298 // Every GET_SERVICE_LOG_EVERY_CALLS calls, log the total time spent in getService().
299
300 final int logInterval = isCore
301 ? GET_SERVICE_LOG_EVERY_CALLS_CORE
302 : GET_SERVICE_LOG_EVERY_CALLS_NON_CORE;
303
304 if ((sGetServiceAccumulatedCallCount >= logInterval)
305 && (nowUptime >= (sLastStatsLogUptime + STATS_LOG_INTERVAL_MS))) {
306
307 EventLogTags.writeServiceManagerStats(
308 sGetServiceAccumulatedCallCount, // Total # of getService() calls.
309 sGetServiceAccumulatedUs / 1000, // Total time spent in getService() calls.
310 (int) (nowUptime - sLastStatsLogUptime)); // Uptime duration since last log.
311 sGetServiceAccumulatedCallCount = 0;
312 sGetServiceAccumulatedUs = 0;
313 sLastStatsLogUptime = nowUptime;
314 }
315 }
316 return binder;
317 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800318}