blob: 17bb3e0f525bf7ce6cff822232f6b2bbad323f56 [file] [log] [blame]
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001/*
2 * Copyright (C) 2012 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 com.android.server.am;
18
19import java.io.FileDescriptor;
20import java.io.IOException;
21import java.io.PrintWriter;
22import java.util.ArrayList;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070023import java.util.HashSet;
24import java.util.Iterator;
25import java.util.List;
26
Dianne Hackborn9210bc82013-09-05 12:31:16 -070027import android.os.Handler;
Dianne Hackborn13c590d2013-10-07 14:32:00 -070028import android.os.Looper;
Dianne Hackborn23037412013-11-04 18:11:29 -080029import android.os.SystemProperties;
Dianne Hackborn9210bc82013-09-05 12:31:16 -070030import android.util.ArrayMap;
Dianne Hackbornd2932242013-08-05 18:18:42 -070031import com.android.internal.app.ProcessStats;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070032import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070033import com.android.internal.os.TransferPipe;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070034import com.android.server.am.ActivityManagerService.ItemMatcher;
35import com.android.server.am.ActivityManagerService.NeededUriGrants;
36
37import android.app.ActivityManager;
38import android.app.AppGlobals;
39import android.app.IApplicationThread;
40import android.app.IServiceConnection;
41import android.app.Notification;
42import android.app.PendingIntent;
43import android.app.Service;
44import android.content.ComponentName;
45import android.content.Context;
46import android.content.Intent;
47import android.content.pm.ApplicationInfo;
48import android.content.pm.PackageManager;
49import android.content.pm.ResolveInfo;
50import android.content.pm.ServiceInfo;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070051import android.os.Binder;
52import android.os.IBinder;
53import android.os.Message;
54import android.os.Process;
55import android.os.RemoteException;
56import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070057import android.os.UserHandle;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070058import android.util.EventLog;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070059import android.util.Slog;
60import android.util.SparseArray;
61import android.util.TimeUtils;
62
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -070063public final class ActiveServices {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070064 static final boolean DEBUG_SERVICE = ActivityManagerService.DEBUG_SERVICE;
65 static final boolean DEBUG_SERVICE_EXECUTING = ActivityManagerService.DEBUG_SERVICE_EXECUTING;
Dianne Hackborn9210bc82013-09-05 12:31:16 -070066 static final boolean DEBUG_DELAYED_SERVICE = ActivityManagerService.DEBUG_SERVICE;
Dianne Hackbornc1742882013-12-09 11:26:11 -080067 static final boolean DEBUG_DELAYED_STARTS = DEBUG_DELAYED_SERVICE;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070068 static final boolean DEBUG_MU = ActivityManagerService.DEBUG_MU;
69 static final String TAG = ActivityManagerService.TAG;
70 static final String TAG_MU = ActivityManagerService.TAG_MU;
71
72 // How long we wait for a service to finish executing.
73 static final int SERVICE_TIMEOUT = 20*1000;
74
Dianne Hackbornbf36ee22013-07-26 18:24:10 -070075 // How long we wait for a service to finish executing.
76 static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
77
Dianne Hackborn599db5c2012-08-03 19:28:48 -070078 // How long a service needs to be running until restarting its process
79 // is no longer considered to be a relaunch of the service.
Dianne Hackborn7b492722013-11-01 09:58:45 -070080 static final int SERVICE_RESTART_DURATION = 1*1000;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070081
82 // How long a service needs to be running until it will start back at
83 // SERVICE_RESTART_DURATION after being killed.
84 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
85
86 // Multiplying factor to increase restart duration time by, for each time
87 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
88 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
89
90 // The minimum amount of time between restarting services that we allow.
91 // That is, when multiple services are restarting, we won't allow each
92 // to restart less than this amount of time from the last one.
93 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
94
95 // Maximum amount of time for there to be no activity on a service before
96 // we consider it non-essential and allow its process to go on the
97 // LRU background list.
98 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
99
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700100 // How long we wait for a background started service to stop itself before
101 // allowing the next pending start to run.
102 static final int BG_START_TIMEOUT = 15*1000;
103
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700104 final ActivityManagerService mAm;
105
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700106 // Maximum number of services that we allow to start in the background
107 // at the same time.
108 final int mMaxStartingBackground;
109
110 final SparseArray<ServiceMap> mServiceMap = new SparseArray<ServiceMap>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700111
112 /**
113 * All currently bound service connections. Keys are the IBinder of
114 * the client's IServiceConnection.
115 */
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700116 final ArrayMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
117 = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700118
119 /**
120 * List of services that we have been asked to start,
121 * but haven't yet been able to. It is used to hold start requests
122 * while waiting for their corresponding application thread to get
123 * going.
124 */
125 final ArrayList<ServiceRecord> mPendingServices
126 = new ArrayList<ServiceRecord>();
127
128 /**
129 * List of services that are scheduled to restart following a crash.
130 */
131 final ArrayList<ServiceRecord> mRestartingServices
132 = new ArrayList<ServiceRecord>();
133
134 /**
Dianne Hackborn164371f2013-10-01 19:10:13 -0700135 * List of services that are in the process of being destroyed.
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700136 */
Dianne Hackborn164371f2013-10-01 19:10:13 -0700137 final ArrayList<ServiceRecord> mDestroyingServices
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700138 = new ArrayList<ServiceRecord>();
139
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700140 static final class DelayingProcess extends ArrayList<ServiceRecord> {
141 long timeoout;
142 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700143
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700144 /**
145 * Information about services for a single user.
146 */
147 class ServiceMap extends Handler {
Dianne Hackborn6285a322013-09-18 12:09:47 -0700148 final int mUserId;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700149 final ArrayMap<ComponentName, ServiceRecord> mServicesByName
150 = new ArrayMap<ComponentName, ServiceRecord>();
151 final ArrayMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent
152 = new ArrayMap<Intent.FilterComparison, ServiceRecord>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700153
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700154 final ArrayList<ServiceRecord> mDelayedStartList
155 = new ArrayList<ServiceRecord>();
156 /* XXX eventually I'd like to have this based on processes instead of services.
157 * That is, if we try to start two services in a row both running in the same
158 * process, this should be one entry in mStartingBackground for that one process
159 * that remains until all services in it are done.
160 final ArrayMap<ProcessRecord, DelayingProcess> mStartingBackgroundMap
161 = new ArrayMap<ProcessRecord, DelayingProcess>();
162 final ArrayList<DelayingProcess> mStartingProcessList
163 = new ArrayList<DelayingProcess>();
164 */
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700165
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700166 final ArrayList<ServiceRecord> mStartingBackground
167 = new ArrayList<ServiceRecord>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700168
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700169 static final int MSG_BG_START_TIMEOUT = 1;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700170
Dianne Hackborn13c590d2013-10-07 14:32:00 -0700171 ServiceMap(Looper looper, int userId) {
172 super(looper);
Dianne Hackborn6285a322013-09-18 12:09:47 -0700173 mUserId = userId;
174 }
175
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700176 @Override
177 public void handleMessage(Message msg) {
178 switch (msg.what) {
179 case MSG_BG_START_TIMEOUT: {
180 synchronized (mAm) {
181 rescheduleDelayedStarts();
182 }
183 } break;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700184 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700185 }
186
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700187 void ensureNotStartingBackground(ServiceRecord r) {
188 if (mStartingBackground.remove(r)) {
Dianne Hackbornc1742882013-12-09 11:26:11 -0800189 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "No longer background starting: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700190 rescheduleDelayedStarts();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700191 }
Dianne Hackborn2e46bb52013-09-13 17:01:26 -0700192 if (mDelayedStartList.remove(r)) {
Dianne Hackbornc1742882013-12-09 11:26:11 -0800193 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "No longer delaying start: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700194 }
195 }
196
197 void rescheduleDelayedStarts() {
198 removeMessages(MSG_BG_START_TIMEOUT);
199 final long now = SystemClock.uptimeMillis();
200 for (int i=0, N=mStartingBackground.size(); i<N; i++) {
201 ServiceRecord r = mStartingBackground.get(i);
202 if (r.startingBgTimeout <= now) {
203 Slog.i(TAG, "Waited long enough for: " + r);
204 mStartingBackground.remove(i);
205 N--;
206 }
207 }
208 while (mDelayedStartList.size() > 0
209 && mStartingBackground.size() < mMaxStartingBackground) {
210 ServiceRecord r = mDelayedStartList.remove(0);
Dianne Hackbornc1742882013-12-09 11:26:11 -0800211 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "REM FR DELAY LIST (exec next): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700212 if (r.pendingStarts.size() <= 0) {
213 Slog.w(TAG, "**** NO PENDING STARTS! " + r + " startReq=" + r.startRequested
214 + " delayedStop=" + r.delayedStop);
215 }
216 if (DEBUG_DELAYED_SERVICE) {
217 if (mDelayedStartList.size() > 0) {
218 Slog.v(TAG, "Remaining delayed list:");
219 for (int i=0; i<mDelayedStartList.size(); i++) {
220 Slog.v(TAG, " #" + i + ": " + mDelayedStartList.get(i));
221 }
222 }
223 }
224 r.delayed = false;
225 startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false, true);
226 }
227 if (mStartingBackground.size() > 0) {
228 ServiceRecord next = mStartingBackground.get(0);
229 long when = next.startingBgTimeout > now ? next.startingBgTimeout : now;
230 if (DEBUG_DELAYED_SERVICE) Slog.v(TAG, "Top bg start is " + next
231 + ", can delay others up to " + when);
232 Message msg = obtainMessage(MSG_BG_START_TIMEOUT);
233 sendMessageAtTime(msg, when);
234 }
Dianne Hackborn6285a322013-09-18 12:09:47 -0700235 if (mStartingBackground.size() < mMaxStartingBackground) {
236 mAm.backgroundServicesFinishedLocked(mUserId);
237 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700238 }
239 }
240
241 public ActiveServices(ActivityManagerService service) {
242 mAm = service;
Dianne Hackborn23037412013-11-04 18:11:29 -0800243 int maxBg = 0;
244 try {
245 maxBg = Integer.parseInt(SystemProperties.get("ro.config.max_starting_bg", "0"));
246 } catch(RuntimeException e) {
247 }
248 mMaxStartingBackground = maxBg > 0 ? maxBg : ActivityManager.isLowRamDeviceStatic() ? 1 : 3;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700249 }
250
251 ServiceRecord getServiceByName(ComponentName name, int callingUser) {
252 // TODO: Deal with global services
253 if (DEBUG_MU)
254 Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
255 return getServiceMap(callingUser).mServicesByName.get(name);
256 }
257
Dianne Hackborn6285a322013-09-18 12:09:47 -0700258 boolean hasBackgroundServices(int callingUser) {
259 ServiceMap smap = mServiceMap.get(callingUser);
260 return smap != null ? smap.mStartingBackground.size() >= mMaxStartingBackground : false;
261 }
262
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700263 private ServiceMap getServiceMap(int callingUser) {
264 ServiceMap smap = mServiceMap.get(callingUser);
265 if (smap == null) {
Dianne Hackborn13c590d2013-10-07 14:32:00 -0700266 smap = new ServiceMap(mAm.mHandler.getLooper(), callingUser);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700267 mServiceMap.put(callingUser, smap);
268 }
269 return smap;
270 }
271
272 ArrayMap<ComponentName, ServiceRecord> getServices(int callingUser) {
273 return getServiceMap(callingUser).mServicesByName;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700274 }
275
276 ComponentName startServiceLocked(IApplicationThread caller,
277 Intent service, String resolvedType,
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700278 int callingPid, int callingUid, int userId) {
Dianne Hackbornc1742882013-12-09 11:26:11 -0800279 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "startService: " + service
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700280 + " type=" + resolvedType + " args=" + service.getExtras());
281
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700282 final boolean callerFg;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700283 if (caller != null) {
284 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
285 if (callerApp == null) {
286 throw new SecurityException(
287 "Unable to find app for caller " + caller
288 + " (pid=" + Binder.getCallingPid()
289 + ") when starting service " + service);
290 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700291 callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
292 } else {
293 callerFg = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700294 }
295
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700296
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700297 ServiceLookupResult res =
298 retrieveServiceLocked(service, resolvedType,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700299 callingPid, callingUid, userId, true, callerFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700300 if (res == null) {
301 return null;
302 }
303 if (res.record == null) {
304 return new ComponentName("!", res.permission != null
305 ? res.permission : "private to package");
306 }
307 ServiceRecord r = res.record;
308 NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
309 callingUid, r.packageName, service, service.getFlags(), null);
Dianne Hackbornd6f5b622013-11-11 17:25:37 -0800310 if (unscheduleServiceRestartLocked(r, callingUid, false)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700311 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
312 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700313 r.lastActivity = SystemClock.uptimeMillis();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700314 r.startRequested = true;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700315 r.delayedStop = false;
316 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
317 service, neededGrants));
318
319 final ServiceMap smap = getServiceMap(r.userId);
320 boolean addToStarting = false;
321 if (!callerFg && r.app == null && mAm.mStartedUsers.get(r.userId) != null) {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700322 ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700323 if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700324 // If this is not coming from a foreground caller, then we may want
325 // to delay the start if there are already other background services
326 // that are starting. This is to avoid process start spam when lots
327 // of applications are all handling things like connectivity broadcasts.
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700328 // We only do this for cached processes, because otherwise an application
329 // can have assumptions about calling startService() for a service to run
330 // in its own process, and for that process to not be killed before the
331 // service is started. This is especially the case for receivers, which
332 // may start a service in onReceive() to do some additional work and have
333 // initialized some global state as part of that.
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700334 if (DEBUG_DELAYED_SERVICE) Slog.v(TAG, "Potential start delay of " + r + " in "
335 + proc);
336 if (r.delayed) {
337 // This service is already scheduled for a delayed start; just leave
338 // it still waiting.
Dianne Hackbornc1742882013-12-09 11:26:11 -0800339 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Continuing to delay: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700340 return r.name;
341 }
342 if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
343 // Something else is starting, delay!
344 Slog.i(TAG, "Delaying start of: " + r);
345 smap.mDelayedStartList.add(r);
346 r.delayed = true;
347 return r.name;
348 }
Dianne Hackbornc1742882013-12-09 11:26:11 -0800349 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Not delaying: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700350 addToStarting = true;
351 } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
352 // We slightly loosen when we will enqueue this new service as a background
353 // starting service we are waiting for, to also include processes that are
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700354 // currently running other services or receivers.
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700355 addToStarting = true;
Dianne Hackbornc1742882013-12-09 11:26:11 -0800356 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Not delaying, but counting as bg: " + r);
357 } else if (DEBUG_DELAYED_STARTS) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700358 StringBuilder sb = new StringBuilder(128);
359 sb.append("Not potential delay (state=").append(proc.curProcState)
360 .append(' ').append(proc.adjType);
361 String reason = proc.makeAdjReason();
362 if (reason != null) {
363 sb.append(' ');
364 sb.append(reason);
365 }
366 sb.append("): ");
367 sb.append(r.toString());
368 Slog.v(TAG, sb.toString());
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700369 }
Dianne Hackbornc1742882013-12-09 11:26:11 -0800370 } else if (DEBUG_DELAYED_STARTS) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700371 if (callerFg) {
372 Slog.v(TAG, "Not potential delay (callerFg=" + callerFg + " uid="
373 + callingUid + " pid=" + callingPid + "): " + r);
374 } else if (r.app != null) {
375 Slog.v(TAG, "Not potential delay (cur app=" + r.app + "): " + r);
376 } else {
377 Slog.v(TAG, "Not potential delay (user " + r.userId + " not started): " + r);
378 }
379 }
380
381 return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
382 }
383
384 ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
385 ServiceRecord r, boolean callerFg, boolean addToStarting) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700386 ProcessStats.ServiceState stracker = r.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -0700387 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700388 stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700389 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700390 r.callStart = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700391 synchronized (r.stats.getBatteryStats()) {
392 r.stats.startRunningLocked();
393 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700394 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -0700395 if (error != null) {
396 return new ComponentName("!!", error);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700397 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700398
399 if (r.startRequested && addToStarting) {
400 boolean first = smap.mStartingBackground.size() == 0;
401 smap.mStartingBackground.add(r);
402 r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
403 if (DEBUG_DELAYED_SERVICE) {
404 RuntimeException here = new RuntimeException("here");
405 here.fillInStackTrace();
406 Slog.v(TAG, "Starting background (first=" + first + "): " + r, here);
Dianne Hackbornc1742882013-12-09 11:26:11 -0800407 } else if (DEBUG_DELAYED_STARTS) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700408 Slog.v(TAG, "Starting background (first=" + first + "): " + r);
409 }
410 if (first) {
411 smap.rescheduleDelayedStarts();
412 }
413 } else if (callerFg) {
414 smap.ensureNotStartingBackground(r);
415 }
416
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700417 return r.name;
418 }
419
420 private void stopServiceLocked(ServiceRecord service) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700421 if (service.delayed) {
422 // If service isn't actually running, but is is being held in the
423 // delayed list, then we need to keep it started but note that it
424 // should be stopped once no longer delayed.
Dianne Hackbornc1742882013-12-09 11:26:11 -0800425 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Delaying stop of pending: " + service);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700426 service.delayedStop = true;
427 return;
428 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700429 synchronized (service.stats.getBatteryStats()) {
430 service.stats.stopRunningLocked();
431 }
432 service.startRequested = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700433 if (service.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700434 service.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700435 SystemClock.uptimeMillis());
436 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700437 service.callStart = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700438 bringDownServiceIfNeededLocked(service, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700439 }
440
441 int stopServiceLocked(IApplicationThread caller, Intent service,
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700442 String resolvedType, int userId) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700443 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
444 + " type=" + resolvedType);
445
446 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
447 if (caller != null && callerApp == null) {
448 throw new SecurityException(
449 "Unable to find app for caller " + caller
450 + " (pid=" + Binder.getCallingPid()
451 + ") when stopping service " + service);
452 }
453
454 // If this service is active, make sure it is stopped.
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -0700455 ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700456 Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700457 if (r != null) {
458 if (r.record != null) {
459 final long origId = Binder.clearCallingIdentity();
460 try {
461 stopServiceLocked(r.record);
462 } finally {
463 Binder.restoreCallingIdentity(origId);
464 }
465 return 1;
466 }
467 return -1;
468 }
469
470 return 0;
471 }
472
473 IBinder peekServiceLocked(Intent service, String resolvedType) {
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -0700474 ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
475 Binder.getCallingPid(), Binder.getCallingUid(),
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700476 UserHandle.getCallingUserId(), false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700477
478 IBinder ret = null;
479 if (r != null) {
480 // r.record is null if findServiceLocked() failed the caller permission check
481 if (r.record == null) {
482 throw new SecurityException(
483 "Permission Denial: Accessing service " + r.record.name
484 + " from pid=" + Binder.getCallingPid()
485 + ", uid=" + Binder.getCallingUid()
486 + " requires " + r.permission);
487 }
488 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
489 if (ib != null) {
490 ret = ib.binder;
491 }
492 }
493
494 return ret;
495 }
496
497 boolean stopServiceTokenLocked(ComponentName className, IBinder token,
498 int startId) {
499 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
500 + " " + token + " startId=" + startId);
Dianne Hackborn41203752012-08-31 14:05:51 -0700501 ServiceRecord r = findServiceLocked(className, token, UserHandle.getCallingUserId());
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700502 if (r != null) {
503 if (startId >= 0) {
504 // Asked to only stop if done with all work. Note that
505 // to avoid leaks, we will take this as dropping all
506 // start items up to and including this one.
507 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
508 if (si != null) {
509 while (r.deliveredStarts.size() > 0) {
510 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
511 cur.removeUriPermissionsLocked();
512 if (cur == si) {
513 break;
514 }
515 }
516 }
517
518 if (r.getLastStartId() != startId) {
519 return false;
520 }
521
522 if (r.deliveredStarts.size() > 0) {
523 Slog.w(TAG, "stopServiceToken startId " + startId
524 + " is last, but have " + r.deliveredStarts.size()
525 + " remaining args");
526 }
527 }
528
529 synchronized (r.stats.getBatteryStats()) {
530 r.stats.stopRunningLocked();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700531 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700532 r.startRequested = false;
533 if (r.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700534 r.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700535 SystemClock.uptimeMillis());
536 }
537 r.callStart = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700538 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700539 bringDownServiceIfNeededLocked(r, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700540 Binder.restoreCallingIdentity(origId);
541 return true;
542 }
543 return false;
544 }
545
546 public void setServiceForegroundLocked(ComponentName className, IBinder token,
547 int id, Notification notification, boolean removeNotification) {
Dianne Hackborn41203752012-08-31 14:05:51 -0700548 final int userId = UserHandle.getCallingUserId();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700549 final long origId = Binder.clearCallingIdentity();
550 try {
Dianne Hackborn41203752012-08-31 14:05:51 -0700551 ServiceRecord r = findServiceLocked(className, token, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700552 if (r != null) {
553 if (id != 0) {
554 if (notification == null) {
555 throw new IllegalArgumentException("null notification");
556 }
557 if (r.foregroundId != id) {
558 r.cancelNotification();
559 r.foregroundId = id;
560 }
561 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
562 r.foregroundNoti = notification;
563 r.isForeground = true;
564 r.postNotification();
565 if (r.app != null) {
566 updateServiceForegroundLocked(r.app, true);
567 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700568 getServiceMap(r.userId).ensureNotStartingBackground(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700569 } else {
570 if (r.isForeground) {
571 r.isForeground = false;
572 if (r.app != null) {
Dianne Hackborndb926082013-10-31 16:32:44 -0700573 mAm.updateLruProcessLocked(r.app, false, null);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700574 updateServiceForegroundLocked(r.app, true);
575 }
576 }
577 if (removeNotification) {
578 r.cancelNotification();
579 r.foregroundId = 0;
580 r.foregroundNoti = null;
581 }
582 }
583 }
584 } finally {
585 Binder.restoreCallingIdentity(origId);
586 }
587 }
588
589 private void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
590 boolean anyForeground = false;
Dianne Hackbornc8230512013-07-13 21:32:12 -0700591 for (int i=proc.services.size()-1; i>=0; i--) {
592 ServiceRecord sr = proc.services.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700593 if (sr.isForeground) {
594 anyForeground = true;
595 break;
596 }
597 }
598 if (anyForeground != proc.foregroundServices) {
599 proc.foregroundServices = anyForeground;
600 if (oomAdj) {
601 mAm.updateOomAdjLocked();
602 }
603 }
604 }
605
Dianne Hackborndb926082013-10-31 16:32:44 -0700606 private boolean updateServiceClientActivitiesLocked(ProcessRecord proc,
607 ConnectionRecord modCr) {
608 if (modCr != null && modCr.binding.client != null) {
609 if (modCr.binding.client.activities.size() <= 0) {
610 // This connection is from a client without activities, so adding
611 // and removing is not interesting.
612 return false;
613 }
614 }
615
616 boolean anyClientActivities = false;
617 for (int i=proc.services.size()-1; i>=0 && !anyClientActivities; i--) {
618 ServiceRecord sr = proc.services.valueAt(i);
619 for (int conni=sr.connections.size()-1; conni>=0 && !anyClientActivities; conni--) {
620 ArrayList<ConnectionRecord> clist = sr.connections.valueAt(conni);
621 for (int cri=clist.size()-1; cri>=0; cri--) {
622 ConnectionRecord cr = clist.get(cri);
623 if (cr.binding.client == null || cr.binding.client == proc) {
624 // Binding to ourself is not interesting.
625 continue;
626 }
627 if (cr.binding.client.activities.size() > 0) {
628 anyClientActivities = true;
629 break;
630 }
631 }
632 }
633 }
634 if (anyClientActivities != proc.hasClientActivities) {
635 proc.hasClientActivities = anyClientActivities;
636 mAm.updateLruProcessLocked(proc, anyClientActivities, null);
637 return true;
638 }
639 return false;
640 }
641
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700642 int bindServiceLocked(IApplicationThread caller, IBinder token,
643 Intent service, String resolvedType,
644 IServiceConnection connection, int flags, int userId) {
645 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
646 + " type=" + resolvedType + " conn=" + connection.asBinder()
647 + " flags=0x" + Integer.toHexString(flags));
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700648 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
649 if (callerApp == null) {
650 throw new SecurityException(
651 "Unable to find app for caller " + caller
652 + " (pid=" + Binder.getCallingPid()
653 + ") when binding service " + service);
654 }
655
656 ActivityRecord activity = null;
657 if (token != null) {
Craig Mautnerd2328952013-03-05 12:46:26 -0800658 activity = ActivityRecord.isInStackLocked(token);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700659 if (activity == null) {
660 Slog.w(TAG, "Binding with unknown activity: " + token);
661 return 0;
662 }
663 }
664
665 int clientLabel = 0;
666 PendingIntent clientIntent = null;
667
668 if (callerApp.info.uid == Process.SYSTEM_UID) {
669 // Hacky kind of thing -- allow system stuff to tell us
670 // what they are, so we can report this elsewhere for
671 // others to know why certain services are running.
672 try {
673 clientIntent = (PendingIntent)service.getParcelableExtra(
674 Intent.EXTRA_CLIENT_INTENT);
675 } catch (RuntimeException e) {
676 }
677 if (clientIntent != null) {
678 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
679 if (clientLabel != 0) {
680 // There are no useful extras in the intent, trash them.
681 // System code calling with this stuff just needs to know
682 // this will happen.
683 service = service.cloneFilter();
684 }
685 }
686 }
687
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700688 final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
689
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700690 ServiceLookupResult res =
691 retrieveServiceLocked(service, resolvedType,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700692 Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700693 if (res == null) {
694 return 0;
695 }
696 if (res.record == null) {
697 return -1;
698 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700699 ServiceRecord s = res.record;
700
701 final long origId = Binder.clearCallingIdentity();
702
703 try {
Dianne Hackbornd6f5b622013-11-11 17:25:37 -0800704 if (unscheduleServiceRestartLocked(s, callerApp.info.uid, false)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700705 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
706 + s);
707 }
708
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700709 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
710 s.lastActivity = SystemClock.uptimeMillis();
711 if (!s.hasAutoCreateConnections()) {
712 // This is the first binding, let the tracker know.
Dianne Hackbornd2932242013-08-05 18:18:42 -0700713 ProcessStats.ServiceState stracker = s.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -0700714 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700715 stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700716 s.lastActivity);
717 }
718 }
719 }
720
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700721 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
722 ConnectionRecord c = new ConnectionRecord(b, activity,
723 connection, flags, clientLabel, clientIntent);
724
725 IBinder binder = connection.asBinder();
726 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
727 if (clist == null) {
728 clist = new ArrayList<ConnectionRecord>();
729 s.connections.put(binder, clist);
730 }
731 clist.add(c);
732 b.connections.add(c);
733 if (activity != null) {
734 if (activity.connections == null) {
735 activity.connections = new HashSet<ConnectionRecord>();
736 }
737 activity.connections.add(c);
738 }
739 b.client.connections.add(c);
740 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
741 b.client.hasAboveClient = true;
742 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700743 if (s.app != null) {
744 updateServiceClientActivitiesLocked(s.app, c);
745 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700746 clist = mServiceConnections.get(binder);
747 if (clist == null) {
748 clist = new ArrayList<ConnectionRecord>();
749 mServiceConnections.put(binder, clist);
750 }
751 clist.add(c);
752
753 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
754 s.lastActivity = SystemClock.uptimeMillis();
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700755 if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700756 return 0;
757 }
758 }
759
760 if (s.app != null) {
761 // This could have made the service more important.
Dianne Hackborndb926082013-10-31 16:32:44 -0700762 mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities, b.client);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700763 mAm.updateOomAdjLocked(s.app);
764 }
765
766 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
767 + ": received=" + b.intent.received
768 + " apps=" + b.intent.apps.size()
769 + " doRebind=" + b.intent.doRebind);
770
771 if (s.app != null && b.intent.received) {
772 // Service is already running, so we can immediately
773 // publish the connection.
774 try {
775 c.conn.connected(s.name, b.intent.binder);
776 } catch (Exception e) {
777 Slog.w(TAG, "Failure sending service " + s.shortName
778 + " to connection " + c.conn.asBinder()
779 + " (in " + c.binding.client.processName + ")", e);
780 }
781
782 // If this is the first app connected back to this binding,
783 // and the service had previously asked to be told when
784 // rebound, then do so.
785 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700786 requestServiceBindingLocked(s, b.intent, callerFg, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700787 }
788 } else if (!b.intent.requested) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700789 requestServiceBindingLocked(s, b.intent, callerFg, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700790 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700791
792 getServiceMap(s.userId).ensureNotStartingBackground(s);
793
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700794 } finally {
795 Binder.restoreCallingIdentity(origId);
796 }
797
798 return 1;
799 }
800
801 void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
802 final long origId = Binder.clearCallingIdentity();
803 try {
804 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
805 + " " + intent + ": " + service);
806 if (r != null) {
807 Intent.FilterComparison filter
808 = new Intent.FilterComparison(intent);
809 IntentBindRecord b = r.bindings.get(filter);
810 if (b != null && !b.received) {
811 b.binder = service;
812 b.requested = true;
813 b.received = true;
Dianne Hackborn390517b2013-05-30 15:03:32 -0700814 for (int conni=r.connections.size()-1; conni>=0; conni--) {
815 ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
816 for (int i=0; i<clist.size(); i++) {
817 ConnectionRecord c = clist.get(i);
818 if (!filter.equals(c.binding.intent.intent)) {
819 if (DEBUG_SERVICE) Slog.v(
820 TAG, "Not publishing to: " + c);
821 if (DEBUG_SERVICE) Slog.v(
822 TAG, "Bound intent: " + c.binding.intent.intent);
823 if (DEBUG_SERVICE) Slog.v(
824 TAG, "Published intent: " + intent);
825 continue;
826 }
827 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
828 try {
829 c.conn.connected(r.name, service);
830 } catch (Exception e) {
831 Slog.w(TAG, "Failure sending service " + r.name +
832 " to connection " + c.conn.asBinder() +
833 " (in " + c.binding.client.processName + ")", e);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700834 }
835 }
836 }
837 }
838
Dianne Hackborn164371f2013-10-01 19:10:13 -0700839 serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700840 }
841 } finally {
842 Binder.restoreCallingIdentity(origId);
843 }
844 }
845
846 boolean unbindServiceLocked(IServiceConnection connection) {
847 IBinder binder = connection.asBinder();
848 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
849 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
850 if (clist == null) {
851 Slog.w(TAG, "Unbind failed: could not find connection for "
852 + connection.asBinder());
853 return false;
854 }
855
856 final long origId = Binder.clearCallingIdentity();
857 try {
858 while (clist.size() > 0) {
859 ConnectionRecord r = clist.get(0);
860 removeConnectionLocked(r, null, null);
861
862 if (r.binding.service.app != null) {
863 // This could have made the service less important.
864 mAm.updateOomAdjLocked(r.binding.service.app);
865 }
866 }
867 } finally {
868 Binder.restoreCallingIdentity(origId);
869 }
870
871 return true;
872 }
873
874 void unbindFinishedLocked(ServiceRecord r, Intent intent, boolean doRebind) {
875 final long origId = Binder.clearCallingIdentity();
876 try {
877 if (r != null) {
878 Intent.FilterComparison filter
879 = new Intent.FilterComparison(intent);
880 IntentBindRecord b = r.bindings.get(filter);
881 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
882 + " at " + b + ": apps="
883 + (b != null ? b.apps.size() : 0));
884
Dianne Hackborn164371f2013-10-01 19:10:13 -0700885 boolean inDestroying = mDestroyingServices.contains(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700886 if (b != null) {
Dianne Hackborn164371f2013-10-01 19:10:13 -0700887 if (b.apps.size() > 0 && !inDestroying) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700888 // Applications have already bound since the last
889 // unbind, so just rebind right here.
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700890 boolean inFg = false;
891 for (int i=b.apps.size()-1; i>=0; i--) {
892 ProcessRecord client = b.apps.valueAt(i).client;
893 if (client != null && client.setSchedGroup
894 != Process.THREAD_GROUP_BG_NONINTERACTIVE) {
895 inFg = true;
896 break;
897 }
898 }
899 requestServiceBindingLocked(r, b, inFg, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700900 } else {
901 // Note to tell the service the next time there is
902 // a new client.
903 b.doRebind = true;
904 }
905 }
906
Dianne Hackborn164371f2013-10-01 19:10:13 -0700907 serviceDoneExecutingLocked(r, inDestroying, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700908 }
909 } finally {
910 Binder.restoreCallingIdentity(origId);
911 }
912 }
913
914 private final ServiceRecord findServiceLocked(ComponentName name,
Dianne Hackborn41203752012-08-31 14:05:51 -0700915 IBinder token, int userId) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700916 ServiceRecord r = getServiceByName(name, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700917 return r == token ? r : null;
918 }
919
920 private final class ServiceLookupResult {
921 final ServiceRecord record;
922 final String permission;
923
924 ServiceLookupResult(ServiceRecord _record, String _permission) {
925 record = _record;
926 permission = _permission;
927 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700928 }
929
930 private class ServiceRestarter implements Runnable {
931 private ServiceRecord mService;
932
933 void setService(ServiceRecord service) {
934 mService = service;
935 }
936
937 public void run() {
938 synchronized(mAm) {
939 performServiceRestartLocked(mService);
940 }
941 }
942 }
943
944 private ServiceLookupResult retrieveServiceLocked(Intent service,
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -0700945 String resolvedType, int callingPid, int callingUid, int userId,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700946 boolean createIfNeeded, boolean callingFromFg) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700947 ServiceRecord r = null;
948 if (DEBUG_SERVICE) Slog.v(TAG, "retrieveServiceLocked: " + service
949 + " type=" + resolvedType + " callingUid=" + callingUid);
950
Dianne Hackborn139748f2012-09-24 11:36:57 -0700951 userId = mAm.handleIncomingUser(callingPid, callingUid, userId,
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700952 false, true, "service", null);
953
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700954 ServiceMap smap = getServiceMap(userId);
955 final ComponentName comp = service.getComponent();
956 if (comp != null) {
957 r = smap.mServicesByName.get(comp);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700958 }
959 if (r == null) {
960 Intent.FilterComparison filter = new Intent.FilterComparison(service);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700961 r = smap.mServicesByIntent.get(filter);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700962 }
963 if (r == null) {
964 try {
965 ResolveInfo rInfo =
966 AppGlobals.getPackageManager().resolveService(
967 service, resolvedType,
968 ActivityManagerService.STOCK_PM_FLAGS, userId);
969 ServiceInfo sInfo =
970 rInfo != null ? rInfo.serviceInfo : null;
971 if (sInfo == null) {
Amith Yamasani2b914652012-08-27 12:04:40 -0700972 Slog.w(TAG, "Unable to start service " + service + " U=" + userId +
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700973 ": not found");
974 return null;
975 }
976 ComponentName name = new ComponentName(
977 sInfo.applicationInfo.packageName, sInfo.name);
978 if (userId > 0) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700979 if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
980 sInfo.name, sInfo.flags)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700981 userId = 0;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700982 smap = getServiceMap(0);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700983 }
984 sInfo = new ServiceInfo(sInfo);
985 sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
986 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700987 r = smap.mServicesByName.get(name);
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -0700988 if (r == null && createIfNeeded) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700989 Intent.FilterComparison filter
990 = new Intent.FilterComparison(service.cloneFilter());
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700991 ServiceRestarter res = new ServiceRestarter();
992 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
993 BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics();
994 synchronized (stats) {
995 ss = stats.getServiceStatsLocked(
996 sInfo.applicationInfo.uid, sInfo.packageName,
997 sInfo.name);
998 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700999 r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001000 res.setService(r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001001 smap.mServicesByName.put(name, r);
1002 smap.mServicesByIntent.put(filter, r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001003
1004 // Make sure this component isn't in the pending list.
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001005 for (int i=mPendingServices.size()-1; i>=0; i--) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001006 ServiceRecord pr = mPendingServices.get(i);
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001007 if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
1008 && pr.name.equals(name)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001009 mPendingServices.remove(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001010 }
1011 }
1012 }
1013 } catch (RemoteException ex) {
1014 // pm is in same process, this will never happen.
1015 }
1016 }
1017 if (r != null) {
1018 if (mAm.checkComponentPermission(r.permission,
1019 callingPid, callingUid, r.appInfo.uid, r.exported)
1020 != PackageManager.PERMISSION_GRANTED) {
1021 if (!r.exported) {
1022 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
1023 + " from pid=" + callingPid
1024 + ", uid=" + callingUid
1025 + " that is not exported from uid " + r.appInfo.uid);
1026 return new ServiceLookupResult(null, "not exported from uid "
1027 + r.appInfo.uid);
1028 }
1029 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
1030 + " from pid=" + callingPid
1031 + ", uid=" + callingUid
1032 + " requires " + r.permission);
1033 return new ServiceLookupResult(null, r.permission);
1034 }
Ben Gruverf5323fe2013-07-31 15:09:51 -07001035 if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
1036 resolvedType, r.appInfo)) {
Ben Gruverb6223792013-07-29 16:35:40 -07001037 return null;
1038 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001039 return new ServiceLookupResult(r, null);
1040 }
1041 return null;
1042 }
1043
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001044 private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001045 if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001046 + why + " of " + r + " in app " + r.app);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001047 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, ">>> EXECUTING "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001048 + why + " of " + r.shortName);
1049 long now = SystemClock.uptimeMillis();
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001050 if (r.executeNesting == 0) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001051 r.executeFg = fg;
Dianne Hackbornd2932242013-08-05 18:18:42 -07001052 ProcessStats.ServiceState stracker = r.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001053 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001054 stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001055 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001056 if (r.app != null) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001057 r.app.executingServices.add(r);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001058 r.app.execServicesFg |= fg;
Dianne Hackborn2be00932013-09-22 16:46:00 -07001059 if (r.app.executingServices.size() == 1) {
1060 scheduleServiceTimeoutLocked(r.app);
1061 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001062 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001063 } else if (r.app != null && fg && !r.app.execServicesFg) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001064 r.app.execServicesFg = true;
Dianne Hackborn2be00932013-09-22 16:46:00 -07001065 scheduleServiceTimeoutLocked(r.app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001066 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001067 r.executeFg |= fg;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001068 r.executeNesting++;
1069 r.executingStart = now;
1070 }
1071
1072 private final boolean requestServiceBindingLocked(ServiceRecord r,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001073 IntentBindRecord i, boolean execInFg, boolean rebind) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001074 if (r.app == null || r.app.thread == null) {
1075 // If service is not currently running, can't yet bind.
1076 return false;
1077 }
1078 if ((!i.requested || rebind) && i.apps.size() > 0) {
1079 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001080 bumpServiceExecutingLocked(r, execInFg, "bind");
Dianne Hackborna413dc02013-07-12 12:02:55 -07001081 r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
1082 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
1083 r.app.repProcState);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001084 if (!rebind) {
1085 i.requested = true;
1086 }
1087 i.hasBound = true;
1088 i.doRebind = false;
1089 } catch (RemoteException e) {
1090 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
1091 return false;
1092 }
1093 }
1094 return true;
1095 }
1096
1097 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
1098 boolean allowCancel) {
1099 boolean canceled = false;
1100
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001101 ServiceMap smap = getServiceMap(r.userId);
1102 if (smap.mServicesByName.get(r.name) != r) {
1103 ServiceRecord cur = smap.mServicesByName.get(r.name);
1104 Slog.wtf(TAG, "Attempting to schedule restart of " + r
1105 + " when found in map: " + cur);
1106 return false;
1107 }
1108
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001109 final long now = SystemClock.uptimeMillis();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001110
1111 if ((r.serviceInfo.applicationInfo.flags
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001112 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
1113 long minDuration = SERVICE_RESTART_DURATION;
1114 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001115
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001116 // Any delivered but not yet finished starts should be put back
1117 // on the pending list.
1118 final int N = r.deliveredStarts.size();
1119 if (N > 0) {
1120 for (int i=N-1; i>=0; i--) {
1121 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
1122 si.removeUriPermissionsLocked();
1123 if (si.intent == null) {
1124 // We'll generate this again if needed.
1125 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
1126 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
1127 r.pendingStarts.add(0, si);
1128 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
1129 dur *= 2;
1130 if (minDuration < dur) minDuration = dur;
1131 if (resetTime < dur) resetTime = dur;
1132 } else {
1133 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
1134 + r.name);
1135 canceled = true;
1136 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001137 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001138 r.deliveredStarts.clear();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001139 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001140
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001141 r.totalRestartCount++;
1142 if (r.restartDelay == 0) {
1143 r.restartCount++;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001144 r.restartDelay = minDuration;
1145 } else {
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001146 // If it has been a "reasonably long time" since the service
1147 // was started, then reset our restart duration back to
1148 // the beginning, so we don't infinitely increase the duration
1149 // on a service that just occasionally gets killed (which is
1150 // a normal case, due to process being killed to reclaim memory).
1151 if (now > (r.restartTime+resetTime)) {
1152 r.restartCount = 1;
1153 r.restartDelay = minDuration;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001154 } else {
Dianne Hackborn7b492722013-11-01 09:58:45 -07001155 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
1156 if (r.restartDelay < minDuration) {
1157 r.restartDelay = minDuration;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001158 }
1159 }
1160 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001161
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001162 r.nextRestartTime = now + r.restartDelay;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001163
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001164 // Make sure that we don't end up restarting a bunch of services
1165 // all at the same time.
1166 boolean repeat;
1167 do {
1168 repeat = false;
1169 for (int i=mRestartingServices.size()-1; i>=0; i--) {
1170 ServiceRecord r2 = mRestartingServices.get(i);
1171 if (r2 != r && r.nextRestartTime
1172 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
1173 && r.nextRestartTime
1174 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
1175 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
1176 r.restartDelay = r.nextRestartTime - now;
1177 repeat = true;
1178 break;
1179 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001180 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001181 } while (repeat);
1182
1183 } else {
Dianne Hackborn7b492722013-11-01 09:58:45 -07001184 // Persistent processes are immediately restarted, so there is no
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001185 // reason to hold of on restarting their services.
1186 r.totalRestartCount++;
1187 r.restartCount = 0;
1188 r.restartDelay = 0;
1189 r.nextRestartTime = now;
1190 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001191
1192 if (!mRestartingServices.contains(r)) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001193 r.createdFromFg = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001194 mRestartingServices.add(r);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001195 r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001196 }
1197
1198 r.cancelNotification();
1199
1200 mAm.mHandler.removeCallbacks(r.restarter);
1201 mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime);
1202 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
1203 Slog.w(TAG, "Scheduling restart of crashed service "
1204 + r.shortName + " in " + r.restartDelay + "ms");
1205 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001206 r.userId, r.shortName, r.restartDelay);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001207
1208 return canceled;
1209 }
1210
1211 final void performServiceRestartLocked(ServiceRecord r) {
1212 if (!mRestartingServices.contains(r)) {
1213 return;
1214 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001215 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001216 }
1217
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001218 private final boolean unscheduleServiceRestartLocked(ServiceRecord r, int callingUid,
1219 boolean force) {
1220 if (!force && r.restartDelay == 0) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001221 return false;
1222 }
Dianne Hackborn7b492722013-11-01 09:58:45 -07001223 // Remove from the restarting list; if the service is currently on the
1224 // restarting list, or the call is coming from another app, then this
1225 // service has become of much more interest so we reset the restart interval.
1226 boolean removed = mRestartingServices.remove(r);
1227 if (removed || callingUid != r.appInfo.uid) {
1228 r.resetRestartCounter();
1229 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001230 if (removed) {
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001231 clearRestartingIfNeededLocked(r);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001232 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001233 mAm.mHandler.removeCallbacks(r.restarter);
1234 return true;
1235 }
1236
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001237 private void clearRestartingIfNeededLocked(ServiceRecord r) {
1238 if (r.restartTracker != null) {
1239 // If this is the last restarting record with this tracker, then clear
1240 // the tracker's restarting state.
1241 boolean stillTracking = false;
1242 for (int i=mRestartingServices.size()-1; i>=0; i--) {
1243 if (mRestartingServices.get(i).restartTracker == r.restartTracker) {
1244 stillTracking = true;
1245 break;
1246 }
1247 }
1248 if (!stillTracking) {
1249 r.restartTracker.setRestarting(false, mAm.mProcessStats.getMemFactorLocked(),
1250 SystemClock.uptimeMillis());
1251 r.restartTracker = null;
1252 }
1253 }
1254 }
1255
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001256 private final String bringUpServiceLocked(ServiceRecord r,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001257 int intentFlags, boolean execInFg, boolean whileRestarting) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001258 //Slog.i(TAG, "Bring up service:");
1259 //r.dump(" ");
1260
1261 if (r.app != null && r.app.thread != null) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001262 sendServiceArgsLocked(r, execInFg, false);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001263 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001264 }
1265
1266 if (!whileRestarting && r.restartDelay > 0) {
1267 // If waiting for a restart, then do nothing.
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001268 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001269 }
1270
1271 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
1272
1273 // We are now bringing the service up, so no longer in the
1274 // restarting state.
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001275 if (mRestartingServices.remove(r)) {
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001276 clearRestartingIfNeededLocked(r);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001277 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001278
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001279 // Make sure this service is no longer considered delayed, we are starting it now.
1280 if (r.delayed) {
Dianne Hackbornc1742882013-12-09 11:26:11 -08001281 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "REM FR DELAY LIST (bring up): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001282 getServiceMap(r.userId).mDelayedStartList.remove(r);
1283 r.delayed = false;
1284 }
1285
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001286 // Make sure that the user who owns this service is started. If not,
1287 // we don't want to allow it to run.
1288 if (mAm.mStartedUsers.get(r.userId) == null) {
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001289 String msg = "Unable to launch app "
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001290 + r.appInfo.packageName + "/"
1291 + r.appInfo.uid + " for service "
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001292 + r.intent.getIntent() + ": user " + r.userId + " is stopped";
1293 Slog.w(TAG, msg);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001294 bringDownServiceLocked(r);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001295 return msg;
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001296 }
1297
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001298 // Service is now being launched, its package can't be stopped.
1299 try {
1300 AppGlobals.getPackageManager().setPackageStoppedState(
1301 r.packageName, false, r.userId);
1302 } catch (RemoteException e) {
1303 } catch (IllegalArgumentException e) {
1304 Slog.w(TAG, "Failed trying to unstop package "
1305 + r.packageName + ": " + e);
1306 }
1307
1308 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
1309 final String procName = r.processName;
1310 ProcessRecord app;
1311
1312 if (!isolated) {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001313 app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
1314 if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
1315 + " app=" + app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001316 if (app != null && app.thread != null) {
1317 try {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001318 app.addPackage(r.appInfo.packageName, mAm.mProcessStats);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001319 realStartServiceLocked(r, app, execInFg);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001320 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001321 } catch (RemoteException e) {
1322 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
1323 }
1324
1325 // If a dead object exception was thrown -- fall through to
1326 // restart the application.
1327 }
1328 } else {
1329 // If this service runs in an isolated process, then each time
1330 // we call startProcessLocked() we will get a new isolated
1331 // process, starting another process if we are currently waiting
1332 // for a previous process to come up. To deal with this, we store
1333 // in the service any current isolated process it is running in or
1334 // waiting to have come up.
1335 app = r.isolatedProc;
1336 }
1337
1338 // Not running -- get it started, and enqueue this service record
1339 // to be executed when the app comes up.
1340 if (app == null) {
1341 if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001342 "service", r.name, false, isolated, false)) == null) {
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001343 String msg = "Unable to launch app "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001344 + r.appInfo.packageName + "/"
1345 + r.appInfo.uid + " for service "
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001346 + r.intent.getIntent() + ": process is bad";
1347 Slog.w(TAG, msg);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001348 bringDownServiceLocked(r);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001349 return msg;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001350 }
1351 if (isolated) {
1352 r.isolatedProc = app;
1353 }
1354 }
1355
1356 if (!mPendingServices.contains(r)) {
1357 mPendingServices.add(r);
1358 }
1359
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001360 if (r.delayedStop) {
1361 // Oh and hey we've already been asked to stop!
1362 r.delayedStop = false;
1363 if (r.startRequested) {
Dianne Hackbornc1742882013-12-09 11:26:11 -08001364 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Applying delayed stop (in bring up): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001365 stopServiceLocked(r);
1366 }
1367 }
1368
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001369 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001370 }
1371
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001372 private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07001373 for (int i=r.bindings.size()-1; i>=0; i--) {
1374 IntentBindRecord ibr = r.bindings.valueAt(i);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001375 if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001376 break;
1377 }
1378 }
1379 }
1380
1381 private final void realStartServiceLocked(ServiceRecord r,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001382 ProcessRecord app, boolean execInFg) throws RemoteException {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001383 if (app.thread == null) {
1384 throw new RemoteException();
1385 }
1386 if (DEBUG_MU)
1387 Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
1388 + ", ProcessRecord.uid = " + app.uid);
1389 r.app = app;
1390 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
1391
1392 app.services.add(r);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001393 bumpServiceExecutingLocked(r, execInFg, "create");
Dianne Hackborndb926082013-10-31 16:32:44 -07001394 mAm.updateLruProcessLocked(app, false, null);
1395 mAm.updateOomAdjLocked();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001396
1397 boolean created = false;
1398 try {
Dianne Hackborncf1171642013-07-12 17:26:02 -07001399 String nameTerm;
1400 int lastPeriod = r.shortName.lastIndexOf('.');
1401 nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
Jeff Sharkey9d6d8902012-11-09 17:32:43 -08001402 EventLogTags.writeAmCreateService(
Dianne Hackborncf1171642013-07-12 17:26:02 -07001403 r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001404 synchronized (r.stats.getBatteryStats()) {
1405 r.stats.startLaunchedLocked();
1406 }
1407 mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborna413dc02013-07-12 12:02:55 -07001408 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001409 app.thread.scheduleCreateService(r, r.serviceInfo,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001410 mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
1411 app.repProcState);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001412 r.postNotification();
1413 created = true;
1414 } finally {
1415 if (!created) {
1416 app.services.remove(r);
Dianne Hackbornbc72dce2013-11-11 10:43:38 -08001417 r.app = null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001418 scheduleServiceRestartLocked(r, false);
1419 }
1420 }
1421
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001422 requestServiceBindingsLocked(r, execInFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001423
1424 // If the service is in the started state, and there are no
1425 // pending arguments, then fake up one so its onStartCommand() will
1426 // be called.
1427 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
1428 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
1429 null, null));
1430 }
1431
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001432 sendServiceArgsLocked(r, execInFg, true);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001433
1434 if (r.delayed) {
Dianne Hackbornc1742882013-12-09 11:26:11 -08001435 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "REM FR DELAY LIST (new proc): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001436 getServiceMap(r.userId).mDelayedStartList.remove(r);
1437 r.delayed = false;
1438 }
1439
1440 if (r.delayedStop) {
1441 // Oh and hey we've already been asked to stop!
1442 r.delayedStop = false;
1443 if (r.startRequested) {
Dianne Hackbornc1742882013-12-09 11:26:11 -08001444 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Applying delayed stop (from start): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001445 stopServiceLocked(r);
1446 }
1447 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001448 }
1449
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001450 private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001451 boolean oomAdjusted) {
1452 final int N = r.pendingStarts.size();
1453 if (N == 0) {
1454 return;
1455 }
1456
1457 while (r.pendingStarts.size() > 0) {
1458 try {
1459 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
1460 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
1461 + r + " " + r.intent + " args=" + si.intent);
1462 if (si.intent == null && N > 1) {
1463 // If somehow we got a dummy null intent in the middle,
1464 // then skip it. DO NOT skip a null intent when it is
1465 // the only one in the list -- this is to support the
1466 // onStartCommand(null) case.
1467 continue;
1468 }
1469 si.deliveredTime = SystemClock.uptimeMillis();
1470 r.deliveredStarts.add(si);
1471 si.deliveryCount++;
1472 if (si.neededGrants != null) {
1473 mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
1474 si.getUriPermissionsLocked());
1475 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001476 bumpServiceExecutingLocked(r, execInFg, "start");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001477 if (!oomAdjusted) {
1478 oomAdjusted = true;
1479 mAm.updateOomAdjLocked(r.app);
1480 }
1481 int flags = 0;
1482 if (si.deliveryCount > 1) {
1483 flags |= Service.START_FLAG_RETRY;
1484 }
1485 if (si.doneExecutingCount > 0) {
1486 flags |= Service.START_FLAG_REDELIVERY;
1487 }
1488 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
1489 } catch (RemoteException e) {
1490 // Remote process gone... we'll let the normal cleanup take
1491 // care of this.
1492 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
1493 break;
1494 } catch (Exception e) {
1495 Slog.w(TAG, "Unexpected exception", e);
1496 break;
1497 }
1498 }
1499 }
1500
Dianne Hackborn164371f2013-10-01 19:10:13 -07001501 private final boolean isServiceNeeded(ServiceRecord r, boolean knowConn, boolean hasConn) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001502 // Are we still explicitly being asked to run?
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001503 if (r.startRequested) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001504 return true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001505 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001506
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001507 // Is someone still bound to us keepign us running?
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001508 if (!knowConn) {
1509 hasConn = r.hasAutoCreateConnections();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001510 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001511 if (hasConn) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001512 return true;
1513 }
1514
1515 return false;
1516 }
1517
1518 private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
1519 boolean hasConn) {
1520 //Slog.i(TAG, "Bring down service:");
1521 //r.dump(" ");
1522
1523 if (isServiceNeeded(r, knowConn, hasConn)) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001524 return;
1525 }
1526
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001527 // Are we in the process of launching?
1528 if (mPendingServices.contains(r)) {
1529 return;
1530 }
1531
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001532 bringDownServiceLocked(r);
1533 }
1534
1535 private final void bringDownServiceLocked(ServiceRecord r) {
1536 //Slog.i(TAG, "Bring down service:");
1537 //r.dump(" ");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001538
Dianne Hackborn390517b2013-05-30 15:03:32 -07001539 // Report to all of the connections that the service is no longer
1540 // available.
1541 for (int conni=r.connections.size()-1; conni>=0; conni--) {
1542 ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
1543 for (int i=0; i<c.size(); i++) {
1544 ConnectionRecord cr = c.get(i);
1545 // There is still a connection to the service that is
1546 // being brought down. Mark it as dead.
1547 cr.serviceDead = true;
1548 try {
1549 cr.conn.connected(r.name, null);
1550 } catch (Exception e) {
1551 Slog.w(TAG, "Failure disconnecting service " + r.name +
1552 " to connection " + c.get(i).conn.asBinder() +
1553 " (in " + c.get(i).binding.client.processName + ")", e);
1554 }
1555 }
1556 }
1557
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001558 // Tell the service that it has been unbound.
Dianne Hackborn390517b2013-05-30 15:03:32 -07001559 if (r.app != null && r.app.thread != null) {
1560 for (int i=r.bindings.size()-1; i>=0; i--) {
1561 IntentBindRecord ibr = r.bindings.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001562 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
1563 + ": hasBound=" + ibr.hasBound);
Dianne Hackborn390517b2013-05-30 15:03:32 -07001564 if (ibr.hasBound) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001565 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001566 bumpServiceExecutingLocked(r, false, "bring down unbind");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001567 mAm.updateOomAdjLocked(r.app);
1568 ibr.hasBound = false;
1569 r.app.thread.scheduleUnbindService(r,
1570 ibr.intent.getIntent());
1571 } catch (Exception e) {
1572 Slog.w(TAG, "Exception when unbinding service "
1573 + r.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001574 serviceProcessGoneLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001575 }
1576 }
1577 }
1578 }
1579
1580 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Jeff Sharkey9d6d8902012-11-09 17:32:43 -08001581 EventLogTags.writeAmDestroyService(
1582 r.userId, System.identityHashCode(r), (r.app != null) ? r.app.pid : -1);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001583
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001584 final ServiceMap smap = getServiceMap(r.userId);
1585 smap.mServicesByName.remove(r.name);
1586 smap.mServicesByIntent.remove(r.intent);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001587 r.totalRestartCount = 0;
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001588 unscheduleServiceRestartLocked(r, 0, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001589
1590 // Also make sure it is not on the pending list.
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001591 for (int i=mPendingServices.size()-1; i>=0; i--) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001592 if (mPendingServices.get(i) == r) {
1593 mPendingServices.remove(i);
1594 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001595 }
1596 }
1597
1598 r.cancelNotification();
1599 r.isForeground = false;
1600 r.foregroundId = 0;
1601 r.foregroundNoti = null;
1602
1603 // Clear start entries.
1604 r.clearDeliveredStartsLocked();
1605 r.pendingStarts.clear();
1606
1607 if (r.app != null) {
1608 synchronized (r.stats.getBatteryStats()) {
1609 r.stats.stopLaunchedLocked();
1610 }
1611 r.app.services.remove(r);
1612 if (r.app.thread != null) {
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001613 updateServiceForegroundLocked(r.app, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001614 try {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001615 bumpServiceExecutingLocked(r, false, "destroy");
1616 mDestroyingServices.add(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001617 mAm.updateOomAdjLocked(r.app);
1618 r.app.thread.scheduleStopService(r);
1619 } catch (Exception e) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001620 Slog.w(TAG, "Exception when destroying service "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001621 + r.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001622 serviceProcessGoneLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001623 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001624 } else {
1625 if (DEBUG_SERVICE) Slog.v(
1626 TAG, "Removed service that has no process: " + r);
1627 }
1628 } else {
1629 if (DEBUG_SERVICE) Slog.v(
1630 TAG, "Removed service that is not running: " + r);
1631 }
1632
1633 if (r.bindings.size() > 0) {
1634 r.bindings.clear();
1635 }
1636
1637 if (r.restarter instanceof ServiceRestarter) {
1638 ((ServiceRestarter)r.restarter).setService(null);
1639 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001640
Dianne Hackbornd2932242013-08-05 18:18:42 -07001641 int memFactor = mAm.mProcessStats.getMemFactorLocked();
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001642 long now = SystemClock.uptimeMillis();
1643 if (r.tracker != null) {
1644 r.tracker.setStarted(false, memFactor, now);
1645 r.tracker.setBound(false, memFactor, now);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001646 if (r.executeNesting == 0) {
Dianne Hackborn878deb32013-10-14 16:55:09 -07001647 r.tracker.clearCurrentOwner(r, false);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001648 r.tracker = null;
1649 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001650 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001651
1652 smap.ensureNotStartingBackground(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001653 }
1654
1655 void removeConnectionLocked(
1656 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
1657 IBinder binder = c.conn.asBinder();
1658 AppBindRecord b = c.binding;
1659 ServiceRecord s = b.service;
1660 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
1661 if (clist != null) {
1662 clist.remove(c);
1663 if (clist.size() == 0) {
1664 s.connections.remove(binder);
1665 }
1666 }
1667 b.connections.remove(c);
1668 if (c.activity != null && c.activity != skipAct) {
1669 if (c.activity.connections != null) {
1670 c.activity.connections.remove(c);
1671 }
1672 }
1673 if (b.client != skipApp) {
1674 b.client.connections.remove(c);
1675 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
1676 b.client.updateHasAboveClientLocked();
1677 }
Dianne Hackborndb926082013-10-31 16:32:44 -07001678 if (s.app != null) {
1679 updateServiceClientActivitiesLocked(s.app, c);
1680 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001681 }
1682 clist = mServiceConnections.get(binder);
1683 if (clist != null) {
1684 clist.remove(c);
1685 if (clist.size() == 0) {
1686 mServiceConnections.remove(binder);
1687 }
1688 }
1689
1690 if (b.connections.size() == 0) {
1691 b.intent.apps.remove(b.client);
1692 }
1693
1694 if (!c.serviceDead) {
1695 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
1696 + ": shouldUnbind=" + b.intent.hasBound);
1697 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
1698 && b.intent.hasBound) {
1699 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001700 bumpServiceExecutingLocked(s, false, "unbind");
Dianne Hackborndb926082013-10-31 16:32:44 -07001701 if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0
1702 && s.app.setProcState <= ActivityManager.PROCESS_STATE_RECEIVER) {
1703 // If this service's process is not already in the cached list,
1704 // then update it in the LRU list here because this may be causing
1705 // it to go down there and we want it to start out near the top.
1706 mAm.updateLruProcessLocked(s.app, false, null);
1707 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001708 mAm.updateOomAdjLocked(s.app);
1709 b.intent.hasBound = false;
1710 // Assume the client doesn't want to know about a rebind;
1711 // we will deal with that later if it asks for one.
1712 b.intent.doRebind = false;
1713 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
1714 } catch (Exception e) {
1715 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001716 serviceProcessGoneLocked(s);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001717 }
1718 }
1719
1720 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001721 boolean hasAutoCreate = s.hasAutoCreateConnections();
1722 if (!hasAutoCreate) {
1723 if (s.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001724 s.tracker.setBound(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001725 SystemClock.uptimeMillis());
1726 }
1727 }
1728 bringDownServiceIfNeededLocked(s, true, hasAutoCreate);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001729 }
1730 }
1731 }
1732
1733 void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001734 boolean inDestroying = mDestroyingServices.contains(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001735 if (r != null) {
1736 if (type == 1) {
1737 // This is a call from a service start... take care of
1738 // book-keeping.
1739 r.callStart = true;
1740 switch (res) {
1741 case Service.START_STICKY_COMPATIBILITY:
1742 case Service.START_STICKY: {
1743 // We are done with the associated start arguments.
1744 r.findDeliveredStart(startId, true);
1745 // Don't stop if killed.
1746 r.stopIfKilled = false;
1747 break;
1748 }
1749 case Service.START_NOT_STICKY: {
1750 // We are done with the associated start arguments.
1751 r.findDeliveredStart(startId, true);
1752 if (r.getLastStartId() == startId) {
1753 // There is no more work, and this service
1754 // doesn't want to hang around if killed.
1755 r.stopIfKilled = true;
1756 }
1757 break;
1758 }
1759 case Service.START_REDELIVER_INTENT: {
1760 // We'll keep this item until they explicitly
1761 // call stop for it, but keep track of the fact
1762 // that it was delivered.
1763 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
1764 if (si != null) {
1765 si.deliveryCount = 0;
1766 si.doneExecutingCount++;
1767 // Don't stop if killed.
1768 r.stopIfKilled = true;
1769 }
1770 break;
1771 }
1772 case Service.START_TASK_REMOVED_COMPLETE: {
1773 // Special processing for onTaskRemoved(). Don't
1774 // impact normal onStartCommand() processing.
1775 r.findDeliveredStart(startId, true);
1776 break;
1777 }
1778 default:
1779 throw new IllegalArgumentException(
1780 "Unknown service start result: " + res);
1781 }
1782 if (res == Service.START_STICKY_COMPATIBILITY) {
1783 r.callStart = false;
1784 }
1785 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001786 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn164371f2013-10-01 19:10:13 -07001787 serviceDoneExecutingLocked(r, inDestroying, inDestroying);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001788 Binder.restoreCallingIdentity(origId);
1789 } else {
1790 Slog.w(TAG, "Done executing unknown service from pid "
1791 + Binder.getCallingPid());
1792 }
1793 }
1794
Dianne Hackborn878deb32013-10-14 16:55:09 -07001795 private void serviceProcessGoneLocked(ServiceRecord r) {
1796 if (r.tracker != null) {
1797 int memFactor = mAm.mProcessStats.getMemFactorLocked();
1798 long now = SystemClock.uptimeMillis();
1799 r.tracker.setExecuting(false, memFactor, now);
1800 r.tracker.setBound(false, memFactor, now);
Dianne Hackbornbc72dce2013-11-11 10:43:38 -08001801 r.tracker.setStarted(false, memFactor, now);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001802 }
1803 serviceDoneExecutingLocked(r, true, true);
1804 }
1805
Dianne Hackborn164371f2013-10-01 19:10:13 -07001806 private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
1807 boolean finishing) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001808 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
1809 + ": nesting=" + r.executeNesting
Dianne Hackborn164371f2013-10-01 19:10:13 -07001810 + ", inDestroying=" + inDestroying + ", app=" + r.app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001811 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
1812 r.executeNesting--;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001813 if (r.executeNesting <= 0) {
1814 if (r.app != null) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001815 if (DEBUG_SERVICE) Slog.v(TAG,
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001816 "Nesting at 0 of " + r.shortName);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001817 r.app.execServicesFg = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001818 r.app.executingServices.remove(r);
1819 if (r.app.executingServices.size() == 0) {
1820 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
1821 "No more executingServices of " + r.shortName);
1822 mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001823 } else if (r.executeFg) {
1824 // Need to re-evaluate whether the app still needs to be in the foreground.
1825 for (int i=r.app.executingServices.size()-1; i>=0; i--) {
1826 if (r.app.executingServices.valueAt(i).executeFg) {
1827 r.app.execServicesFg = true;
1828 break;
1829 }
1830 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001831 }
Dianne Hackborn164371f2013-10-01 19:10:13 -07001832 if (inDestroying) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001833 if (DEBUG_SERVICE) Slog.v(TAG,
Dianne Hackborn164371f2013-10-01 19:10:13 -07001834 "doneExecuting remove destroying " + r);
1835 mDestroyingServices.remove(r);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001836 r.bindings.clear();
1837 }
1838 mAm.updateOomAdjLocked(r.app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001839 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001840 r.executeFg = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001841 if (r.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001842 r.tracker.setExecuting(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001843 SystemClock.uptimeMillis());
Dianne Hackborn164371f2013-10-01 19:10:13 -07001844 if (finishing) {
Dianne Hackborn878deb32013-10-14 16:55:09 -07001845 r.tracker.clearCurrentOwner(r, false);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001846 r.tracker = null;
1847 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001848 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001849 if (finishing) {
Dianne Hackborn90e9b1d2013-11-21 12:50:01 -08001850 if (r.app != null && !r.app.persistent) {
Dianne Hackbornddc19e92013-11-14 14:32:17 -08001851 r.app.services.remove(r);
1852 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001853 r.app = null;
1854 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001855 }
1856 }
1857
1858 boolean attachApplicationLocked(ProcessRecord proc, String processName) throws Exception {
1859 boolean didSomething = false;
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001860 // Collect any services that are waiting for this process to come up.
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001861 if (mPendingServices.size() > 0) {
1862 ServiceRecord sr = null;
1863 try {
1864 for (int i=0; i<mPendingServices.size(); i++) {
1865 sr = mPendingServices.get(i);
1866 if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
1867 || !processName.equals(sr.processName))) {
1868 continue;
1869 }
1870
1871 mPendingServices.remove(i);
1872 i--;
Dianne Hackbornd2932242013-08-05 18:18:42 -07001873 proc.addPackage(sr.appInfo.packageName, mAm.mProcessStats);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001874 realStartServiceLocked(sr, proc, sr.createdFromFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001875 didSomething = true;
1876 }
1877 } catch (Exception e) {
1878 Slog.w(TAG, "Exception in new application when starting service "
1879 + sr.shortName, e);
1880 throw e;
1881 }
1882 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001883 // Also, if there are any services that are waiting to restart and
1884 // would run in this process, now is a good time to start them. It would
1885 // be weird to bring up the process but arbitrarily not let the services
1886 // run at this point just because their restart time hasn't come up.
1887 if (mRestartingServices.size() > 0) {
1888 ServiceRecord sr = null;
1889 for (int i=0; i<mRestartingServices.size(); i++) {
1890 sr = mRestartingServices.get(i);
1891 if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
1892 || !processName.equals(sr.processName))) {
1893 continue;
1894 }
1895 mAm.mHandler.removeCallbacks(sr.restarter);
1896 mAm.mHandler.post(sr.restarter);
1897 }
1898 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001899 return didSomething;
1900 }
1901
1902 void processStartTimedOutLocked(ProcessRecord proc) {
1903 for (int i=0; i<mPendingServices.size(); i++) {
1904 ServiceRecord sr = mPendingServices.get(i);
1905 if ((proc.uid == sr.appInfo.uid
1906 && proc.processName.equals(sr.processName))
1907 || sr.isolatedProc == proc) {
1908 Slog.w(TAG, "Forcing bringing down service: " + sr);
1909 sr.isolatedProc = null;
1910 mPendingServices.remove(i);
1911 i--;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001912 bringDownServiceLocked(sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001913 }
1914 }
1915 }
1916
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001917 private boolean collectForceStopServicesLocked(String name, int userId,
1918 boolean evenPersistent, boolean doit,
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001919 ArrayMap<ComponentName, ServiceRecord> services,
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001920 ArrayList<ServiceRecord> result) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001921 boolean didSomething = false;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001922 for (int i=0; i<services.size(); i++) {
1923 ServiceRecord service = services.valueAt(i);
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001924 if ((name == null || service.packageName.equals(name))
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001925 && (service.app == null || evenPersistent || !service.app.persistent)) {
1926 if (!doit) {
1927 return true;
1928 }
1929 didSomething = true;
1930 Slog.i(TAG, " Force stopping service " + service);
1931 if (service.app != null) {
1932 service.app.removed = true;
Dianne Hackborn90e9b1d2013-11-21 12:50:01 -08001933 if (!service.app.persistent) {
1934 service.app.services.remove(service);
1935 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001936 }
1937 service.app = null;
1938 service.isolatedProc = null;
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001939 result.add(service);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001940 }
1941 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001942 return didSomething;
1943 }
1944
1945 boolean forceStopLocked(String name, int userId, boolean evenPersistent, boolean doit) {
1946 boolean didSomething = false;
1947 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
1948 if (userId == UserHandle.USER_ALL) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001949 for (int i=0; i<mServiceMap.size(); i++) {
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001950 didSomething |= collectForceStopServicesLocked(name, userId, evenPersistent,
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001951 doit, mServiceMap.valueAt(i).mServicesByName, services);
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001952 if (!doit && didSomething) {
1953 return true;
1954 }
1955 }
1956 } else {
Amith Yamasani540b6592013-10-01 13:02:52 -07001957 ServiceMap smap = mServiceMap.get(userId);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001958 if (smap != null) {
1959 ArrayMap<ComponentName, ServiceRecord> items = smap.mServicesByName;
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07001960 didSomething = collectForceStopServicesLocked(name, userId, evenPersistent,
1961 doit, items, services);
1962 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001963 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001964
1965 int N = services.size();
1966 for (int i=0; i<N; i++) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001967 bringDownServiceLocked(services.get(i));
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001968 }
1969 return didSomething;
1970 }
1971
1972 void cleanUpRemovedTaskLocked(TaskRecord tr, ComponentName component, Intent baseIntent) {
1973 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001974 ArrayMap<ComponentName, ServiceRecord> alls = getServices(tr.userId);
1975 for (int i=0; i<alls.size(); i++) {
1976 ServiceRecord sr = alls.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001977 if (sr.packageName.equals(component.getPackageName())) {
1978 services.add(sr);
1979 }
1980 }
1981
1982 // Take care of any running services associated with the app.
1983 for (int i=0; i<services.size(); i++) {
1984 ServiceRecord sr = services.get(i);
1985 if (sr.startRequested) {
1986 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
1987 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
1988 stopServiceLocked(sr);
1989 } else {
1990 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
1991 sr.makeNextStartId(), baseIntent, null));
1992 if (sr.app != null && sr.app.thread != null) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001993 // We always run in the foreground, since this is called as
1994 // part of the "remove task" UI operation.
1995 sendServiceArgsLocked(sr, true, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001996 }
1997 }
1998 }
1999 }
2000 }
2001
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002002 final void killServicesLocked(ProcessRecord app, boolean allowRestart) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002003 // Report disconnected services.
2004 if (false) {
2005 // XXX we are letting the client link to the service for
2006 // death notifications.
2007 if (app.services.size() > 0) {
2008 Iterator<ServiceRecord> it = app.services.iterator();
2009 while (it.hasNext()) {
2010 ServiceRecord r = it.next();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002011 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2012 ArrayList<ConnectionRecord> cl = r.connections.valueAt(conni);
2013 for (int i=0; i<cl.size(); i++) {
2014 ConnectionRecord c = cl.get(i);
2015 if (c.binding.client != app) {
2016 try {
2017 //c.conn.connected(r.className, null);
2018 } catch (Exception e) {
2019 // todo: this should be asynchronous!
2020 Slog.w(TAG, "Exception thrown disconnected servce "
2021 + r.shortName
2022 + " from app " + app.processName, e);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002023 }
2024 }
2025 }
2026 }
2027 }
2028 }
2029 }
2030
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002031 // First clear app state from services.
Dianne Hackbornc8230512013-07-13 21:32:12 -07002032 for (int i=app.services.size()-1; i>=0; i--) {
Dianne Hackbornc8230512013-07-13 21:32:12 -07002033 ServiceRecord sr = app.services.valueAt(i);
2034 synchronized (sr.stats.getBatteryStats()) {
2035 sr.stats.stopLaunchedLocked();
2036 }
Dianne Hackbornc1742882013-12-09 11:26:11 -08002037 if (sr.app != app && sr.app != null && !sr.app.persistent) {
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002038 sr.app.services.remove(sr);
2039 }
Dianne Hackbornc8230512013-07-13 21:32:12 -07002040 sr.app = null;
2041 sr.isolatedProc = null;
2042 sr.executeNesting = 0;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002043 sr.forceClearTracker();
2044 if (mDestroyingServices.remove(sr)) {
2045 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove destroying " + sr);
Dianne Hackbornc8230512013-07-13 21:32:12 -07002046 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002047
Dianne Hackbornc8230512013-07-13 21:32:12 -07002048 final int numClients = sr.bindings.size();
2049 for (int bindingi=numClients-1; bindingi>=0; bindingi--) {
2050 IntentBindRecord b = sr.bindings.valueAt(bindingi);
2051 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
2052 + ": shouldUnbind=" + b.hasBound);
2053 b.binder = null;
2054 b.requested = b.received = b.hasBound = false;
2055 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002056 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002057
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002058 // Clean up any connections this application has to other services.
2059 for (int i=app.connections.size()-1; i>=0; i--) {
2060 ConnectionRecord r = app.connections.valueAt(i);
2061 removeConnectionLocked(r, app, null);
2062 }
2063 app.connections.clear();
2064
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002065 ServiceMap smap = getServiceMap(app.userId);
2066
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002067 // Now do remaining service cleanup.
2068 for (int i=app.services.size()-1; i>=0; i--) {
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002069 ServiceRecord sr = app.services.valueAt(i);
Dianne Hackbornc1742882013-12-09 11:26:11 -08002070
2071 // Unless the process is persistent, this process record is going away,
2072 // so make sure the service is cleaned out of it.
2073 if (!app.persistent) {
2074 app.services.removeAt(i);
2075 }
2076
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002077 // Sanity check: if the service listed for the app is not one
Dianne Hackbornc1742882013-12-09 11:26:11 -08002078 // we actually are maintaining, just let it drop.
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002079 if (smap.mServicesByName.get(sr.name) != sr) {
2080 ServiceRecord cur = smap.mServicesByName.get(sr.name);
2081 Slog.wtf(TAG, "Service " + sr + " in process " + app
2082 + " not same as in map: " + cur);
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002083 continue;
2084 }
2085
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002086 // Any services running in the application may need to be placed
2087 // back in the pending list.
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002088 if (allowRestart && sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
Dianne Hackbornc8230512013-07-13 21:32:12 -07002089 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
2090 Slog.w(TAG, "Service crashed " + sr.crashCount
2091 + " times, stopping: " + sr);
2092 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
2093 sr.userId, sr.crashCount, sr.shortName, app.pid);
2094 bringDownServiceLocked(sr);
2095 } else if (!allowRestart) {
2096 bringDownServiceLocked(sr);
2097 } else {
2098 boolean canceled = scheduleServiceRestartLocked(sr, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002099
Dianne Hackbornc8230512013-07-13 21:32:12 -07002100 // Should the service remain running? Note that in the
2101 // extreme case of so many attempts to deliver a command
2102 // that it failed we also will stop it here.
2103 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
2104 if (sr.pendingStarts.size() == 0) {
2105 sr.startRequested = false;
2106 if (sr.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07002107 sr.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackbornc8230512013-07-13 21:32:12 -07002108 SystemClock.uptimeMillis());
2109 }
2110 if (!sr.hasAutoCreateConnections()) {
2111 // Whoops, no reason to restart!
2112 bringDownServiceLocked(sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002113 }
2114 }
2115 }
2116 }
Dianne Hackbornc8230512013-07-13 21:32:12 -07002117 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002118
Dianne Hackbornc8230512013-07-13 21:32:12 -07002119 if (!allowRestart) {
2120 app.services.clear();
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002121
2122 // Make sure there are no more restarting services for this process.
2123 for (int i=mRestartingServices.size()-1; i>=0; i--) {
2124 ServiceRecord r = mRestartingServices.get(i);
2125 if (r.processName.equals(app.processName) &&
2126 r.serviceInfo.applicationInfo.uid == app.info.uid) {
2127 mRestartingServices.remove(i);
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08002128 clearRestartingIfNeededLocked(r);
2129 }
2130 }
2131 for (int i=mPendingServices.size()-1; i>=0; i--) {
2132 ServiceRecord r = mPendingServices.get(i);
2133 if (r.processName.equals(app.processName) &&
2134 r.serviceInfo.applicationInfo.uid == app.info.uid) {
2135 mPendingServices.remove(i);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002136 }
2137 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002138 }
2139
2140 // Make sure we have no more records on the stopping list.
Dianne Hackborn164371f2013-10-01 19:10:13 -07002141 int i = mDestroyingServices.size();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002142 while (i > 0) {
2143 i--;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002144 ServiceRecord sr = mDestroyingServices.get(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002145 if (sr.app == app) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07002146 sr.forceClearTracker();
2147 mDestroyingServices.remove(i);
2148 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove destroying " + sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002149 }
2150 }
2151
2152 app.executingServices.clear();
2153 }
2154
2155 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
2156 ActivityManager.RunningServiceInfo info =
2157 new ActivityManager.RunningServiceInfo();
2158 info.service = r.name;
2159 if (r.app != null) {
2160 info.pid = r.app.pid;
2161 }
2162 info.uid = r.appInfo.uid;
2163 info.process = r.processName;
2164 info.foreground = r.isForeground;
2165 info.activeSince = r.createTime;
2166 info.started = r.startRequested;
2167 info.clientCount = r.connections.size();
2168 info.crashCount = r.crashCount;
2169 info.lastActivityTime = r.lastActivity;
2170 if (r.isForeground) {
2171 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
2172 }
2173 if (r.startRequested) {
2174 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
2175 }
2176 if (r.app != null && r.app.pid == ActivityManagerService.MY_PID) {
2177 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
2178 }
2179 if (r.app != null && r.app.persistent) {
2180 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
2181 }
2182
Dianne Hackborn390517b2013-05-30 15:03:32 -07002183 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2184 ArrayList<ConnectionRecord> connl = r.connections.valueAt(conni);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002185 for (int i=0; i<connl.size(); i++) {
2186 ConnectionRecord conn = connl.get(i);
2187 if (conn.clientLabel != 0) {
2188 info.clientPackage = conn.binding.client.info.packageName;
2189 info.clientLabel = conn.clientLabel;
2190 return info;
2191 }
2192 }
2193 }
2194 return info;
2195 }
2196
2197 List<ActivityManager.RunningServiceInfo> getRunningServiceInfoLocked(int maxNum,
2198 int flags) {
2199 ArrayList<ActivityManager.RunningServiceInfo> res
2200 = new ArrayList<ActivityManager.RunningServiceInfo>();
2201
Dianne Hackborn0c380492012-08-20 17:23:30 -07002202 final int uid = Binder.getCallingUid();
2203 final long ident = Binder.clearCallingIdentity();
2204 try {
2205 if (ActivityManager.checkUidPermission(
2206 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2207 uid) == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn1676c852012-09-10 14:52:30 -07002208 int[] users = mAm.getUsersLocked();
2209 for (int ui=0; ui<users.length && res.size() < maxNum; ui++) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002210 ArrayMap<ComponentName, ServiceRecord> alls = getServices(users[ui]);
2211 for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
2212 ServiceRecord sr = alls.valueAt(i);
2213 res.add(makeRunningServiceInfoLocked(sr));
Dianne Hackborn0c380492012-08-20 17:23:30 -07002214 }
2215 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002216
Dianne Hackborn0c380492012-08-20 17:23:30 -07002217 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
2218 ServiceRecord r = mRestartingServices.get(i);
2219 ActivityManager.RunningServiceInfo info =
2220 makeRunningServiceInfoLocked(r);
2221 info.restarting = r.nextRestartTime;
2222 res.add(info);
2223 }
2224 } else {
2225 int userId = UserHandle.getUserId(uid);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002226 ArrayMap<ComponentName, ServiceRecord> alls = getServices(userId);
2227 for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
2228 ServiceRecord sr = alls.valueAt(i);
2229 res.add(makeRunningServiceInfoLocked(sr));
Dianne Hackborn0c380492012-08-20 17:23:30 -07002230 }
2231
2232 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
2233 ServiceRecord r = mRestartingServices.get(i);
2234 if (r.userId == userId) {
2235 ActivityManager.RunningServiceInfo info =
2236 makeRunningServiceInfoLocked(r);
2237 info.restarting = r.nextRestartTime;
2238 res.add(info);
2239 }
2240 }
2241 }
2242 } finally {
2243 Binder.restoreCallingIdentity(ident);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002244 }
2245
2246 return res;
2247 }
2248
2249 public PendingIntent getRunningServiceControlPanelLocked(ComponentName name) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07002250 int userId = UserHandle.getUserId(Binder.getCallingUid());
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002251 ServiceRecord r = getServiceByName(name, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002252 if (r != null) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002253 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2254 ArrayList<ConnectionRecord> conn = r.connections.valueAt(conni);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002255 for (int i=0; i<conn.size(); i++) {
2256 if (conn.get(i).clientIntent != null) {
2257 return conn.get(i).clientIntent;
2258 }
2259 }
2260 }
2261 }
2262 return null;
2263 }
2264
2265 void serviceTimeout(ProcessRecord proc) {
2266 String anrMessage = null;
2267
2268 synchronized(this) {
2269 if (proc.executingServices.size() == 0 || proc.thread == null) {
2270 return;
2271 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002272 long maxTime = SystemClock.uptimeMillis() -
2273 (proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002274 ServiceRecord timeout = null;
2275 long nextTime = 0;
Dianne Hackbornc8230512013-07-13 21:32:12 -07002276 for (int i=proc.executingServices.size()-1; i>=0; i--) {
2277 ServiceRecord sr = proc.executingServices.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002278 if (sr.executingStart < maxTime) {
2279 timeout = sr;
2280 break;
2281 }
2282 if (sr.executingStart > nextTime) {
2283 nextTime = sr.executingStart;
2284 }
2285 }
2286 if (timeout != null && mAm.mLruProcesses.contains(proc)) {
2287 Slog.w(TAG, "Timeout executing service: " + timeout);
2288 anrMessage = "Executing service " + timeout.shortName;
2289 } else {
2290 Message msg = mAm.mHandler.obtainMessage(
2291 ActivityManagerService.SERVICE_TIMEOUT_MSG);
2292 msg.obj = proc;
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002293 mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg
Dianne Hackborn2be00932013-09-22 16:46:00 -07002294 ? (nextTime+SERVICE_TIMEOUT) : (nextTime + SERVICE_BACKGROUND_TIMEOUT));
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002295 }
2296 }
2297
2298 if (anrMessage != null) {
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -07002299 mAm.appNotResponding(proc, null, null, false, anrMessage);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002300 }
2301 }
2302
Dianne Hackborn2be00932013-09-22 16:46:00 -07002303 void scheduleServiceTimeoutLocked(ProcessRecord proc) {
2304 if (proc.executingServices.size() == 0 || proc.thread == null) {
2305 return;
2306 }
2307 long now = SystemClock.uptimeMillis();
2308 Message msg = mAm.mHandler.obtainMessage(
2309 ActivityManagerService.SERVICE_TIMEOUT_MSG);
2310 msg.obj = proc;
2311 mAm.mHandler.sendMessageAtTime(msg,
2312 proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
2313 }
2314
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002315 /**
2316 * Prints a list of ServiceRecords (dumpsys activity services)
2317 */
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002318 void dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002319 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
2320 boolean needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002321 boolean printedAnything = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002322
2323 ItemMatcher matcher = new ItemMatcher();
2324 matcher.build(args, opti);
2325
2326 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
2327 try {
Dianne Hackborn1676c852012-09-10 14:52:30 -07002328 int[] users = mAm.getUsersLocked();
2329 for (int user : users) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002330 ServiceMap smap = getServiceMap(user);
2331 boolean printed = false;
2332 if (smap.mServicesByName.size() > 0) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002333 long nowReal = SystemClock.elapsedRealtime();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002334 needSep = false;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002335 for (int si=0; si<smap.mServicesByName.size(); si++) {
2336 ServiceRecord r = smap.mServicesByName.valueAt(si);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002337 if (!matcher.match(r, r.name)) {
2338 continue;
2339 }
2340 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2341 continue;
2342 }
2343 if (!printed) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002344 if (printedAnything) {
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07002345 pw.println();
2346 }
Dianne Hackborn1676c852012-09-10 14:52:30 -07002347 pw.println(" User " + user + " active services:");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002348 printed = true;
2349 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002350 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002351 if (needSep) {
2352 pw.println();
2353 }
2354 pw.print(" * ");
2355 pw.println(r);
2356 if (dumpAll) {
2357 r.dump(pw, " ");
2358 needSep = true;
2359 } else {
2360 pw.print(" app=");
2361 pw.println(r.app);
2362 pw.print(" created=");
2363 TimeUtils.formatDuration(r.createTime, nowReal, pw);
2364 pw.print(" started=");
2365 pw.print(r.startRequested);
2366 pw.print(" connections=");
2367 pw.println(r.connections.size());
2368 if (r.connections.size() > 0) {
2369 pw.println(" Connections:");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002370 for (int conni=0; conni<r.connections.size(); conni++) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002371 ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002372 for (int i = 0; i < clist.size(); i++) {
2373 ConnectionRecord conn = clist.get(i);
2374 pw.print(" ");
2375 pw.print(conn.binding.intent.intent.getIntent()
2376 .toShortString(false, false, false, false));
2377 pw.print(" -> ");
2378 ProcessRecord proc = conn.binding.client;
2379 pw.println(proc != null ? proc.toShortString() : "null");
2380 }
2381 }
2382 }
2383 }
2384 if (dumpClient && r.app != null && r.app.thread != null) {
2385 pw.println(" Client:");
2386 pw.flush();
2387 try {
2388 TransferPipe tp = new TransferPipe();
2389 try {
2390 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(),
2391 r, args);
2392 tp.setBufferPrefix(" ");
2393 // Short timeout, since blocking here can
2394 // deadlock with the application.
2395 tp.go(fd, 2000);
2396 } finally {
2397 tp.kill();
2398 }
2399 } catch (IOException e) {
2400 pw.println(" Failure while dumping the service: " + e);
2401 } catch (RemoteException e) {
2402 pw.println(" Got a RemoteException while dumping the service");
2403 }
2404 needSep = true;
2405 }
2406 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002407 needSep |= printed;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002408 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002409 printed = false;
2410 for (int si=0, SN=smap.mDelayedStartList.size(); si<SN; si++) {
2411 ServiceRecord r = smap.mDelayedStartList.get(si);
2412 if (!matcher.match(r, r.name)) {
2413 continue;
2414 }
2415 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2416 continue;
2417 }
2418 if (!printed) {
2419 if (printedAnything) {
2420 pw.println();
2421 }
2422 pw.println(" User " + user + " delayed start services:");
2423 printed = true;
2424 }
2425 printedAnything = true;
2426 pw.print(" * Delayed start "); pw.println(r);
2427 }
2428 printed = false;
2429 for (int si=0, SN=smap.mStartingBackground.size(); si<SN; si++) {
2430 ServiceRecord r = smap.mStartingBackground.get(si);
2431 if (!matcher.match(r, r.name)) {
2432 continue;
2433 }
2434 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2435 continue;
2436 }
2437 if (!printed) {
2438 if (printedAnything) {
2439 pw.println();
2440 }
2441 pw.println(" User " + user + " starting in background:");
2442 printed = true;
2443 }
2444 printedAnything = true;
2445 pw.print(" * Starting bg "); pw.println(r);
2446 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002447 }
Amith Yamasani258848d2012-08-10 17:06:33 -07002448 } catch (Exception e) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002449 Slog.w(TAG, "Exception in dumpServicesLocked", e);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002450 }
2451
2452 if (mPendingServices.size() > 0) {
2453 boolean printed = false;
2454 for (int i=0; i<mPendingServices.size(); i++) {
2455 ServiceRecord r = mPendingServices.get(i);
2456 if (!matcher.match(r, r.name)) {
2457 continue;
2458 }
2459 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2460 continue;
2461 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002462 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002463 if (!printed) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002464 if (needSep) pw.println();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002465 needSep = true;
2466 pw.println(" Pending services:");
2467 printed = true;
2468 }
2469 pw.print(" * Pending "); pw.println(r);
2470 r.dump(pw, " ");
2471 }
2472 needSep = true;
2473 }
2474
2475 if (mRestartingServices.size() > 0) {
2476 boolean printed = false;
2477 for (int i=0; i<mRestartingServices.size(); i++) {
2478 ServiceRecord r = mRestartingServices.get(i);
2479 if (!matcher.match(r, r.name)) {
2480 continue;
2481 }
2482 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2483 continue;
2484 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002485 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002486 if (!printed) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002487 if (needSep) pw.println();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002488 needSep = true;
2489 pw.println(" Restarting services:");
2490 printed = true;
2491 }
2492 pw.print(" * Restarting "); pw.println(r);
2493 r.dump(pw, " ");
2494 }
2495 needSep = true;
2496 }
2497
Dianne Hackborn164371f2013-10-01 19:10:13 -07002498 if (mDestroyingServices.size() > 0) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002499 boolean printed = false;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002500 for (int i=0; i< mDestroyingServices.size(); i++) {
2501 ServiceRecord r = mDestroyingServices.get(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002502 if (!matcher.match(r, r.name)) {
2503 continue;
2504 }
2505 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2506 continue;
2507 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002508 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002509 if (!printed) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002510 if (needSep) pw.println();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002511 needSep = true;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002512 pw.println(" Destroying services:");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002513 printed = true;
2514 }
Dianne Hackborn164371f2013-10-01 19:10:13 -07002515 pw.print(" * Destroy "); pw.println(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002516 r.dump(pw, " ");
2517 }
2518 needSep = true;
2519 }
2520
2521 if (dumpAll) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002522 boolean printed = false;
2523 for (int ic=0; ic<mServiceConnections.size(); ic++) {
2524 ArrayList<ConnectionRecord> r = mServiceConnections.valueAt(ic);
2525 for (int i=0; i<r.size(); i++) {
2526 ConnectionRecord cr = r.get(i);
2527 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
2528 continue;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002529 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002530 if (dumpPackage != null && (cr.binding.client == null
2531 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
2532 continue;
2533 }
2534 printedAnything = true;
2535 if (!printed) {
2536 if (needSep) pw.println();
2537 needSep = true;
2538 pw.println(" Connection bindings to services:");
2539 printed = true;
2540 }
2541 pw.print(" * "); pw.println(cr);
2542 cr.dump(pw, " ");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002543 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002544 }
2545 }
2546
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002547 if (!printedAnything) {
2548 pw.println(" (nothing)");
2549 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002550 }
2551
2552 /**
2553 * There are three ways to call this:
2554 * - no service specified: dump all the services
2555 * - a flattened component name that matched an existing service was specified as the
2556 * first arg: dump that one service
2557 * - the first arg isn't the flattened component name of an existing service:
2558 * dump all services whose component contains the first arg as a substring
2559 */
2560 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
2561 int opti, boolean dumpAll) {
2562 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
2563
Dianne Hackborn1676c852012-09-10 14:52:30 -07002564 synchronized (this) {
2565 int[] users = mAm.getUsersLocked();
2566 if ("all".equals(name)) {
2567 for (int user : users) {
Dianne Hackborn13c590d2013-10-07 14:32:00 -07002568 ServiceMap smap = mServiceMap.get(user);
2569 if (smap == null) {
2570 continue;
2571 }
2572 ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002573 for (int i=0; i<alls.size(); i++) {
2574 ServiceRecord r1 = alls.valueAt(i);
Amith Yamasani258848d2012-08-10 17:06:33 -07002575 services.add(r1);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002576 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002577 }
Dianne Hackborn1676c852012-09-10 14:52:30 -07002578 } else {
2579 ComponentName componentName = name != null
2580 ? ComponentName.unflattenFromString(name) : null;
2581 int objectId = 0;
2582 if (componentName == null) {
2583 // Not a '/' separated full component name; maybe an object ID?
2584 try {
2585 objectId = Integer.parseInt(name, 16);
2586 name = null;
2587 componentName = null;
2588 } catch (RuntimeException e) {
2589 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002590 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002591
Dianne Hackborn1676c852012-09-10 14:52:30 -07002592 for (int user : users) {
Dianne Hackborn13c590d2013-10-07 14:32:00 -07002593 ServiceMap smap = mServiceMap.get(user);
2594 if (smap == null) {
2595 continue;
2596 }
2597 ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002598 for (int i=0; i<alls.size(); i++) {
2599 ServiceRecord r1 = alls.valueAt(i);
Amith Yamasani258848d2012-08-10 17:06:33 -07002600 if (componentName != null) {
2601 if (r1.name.equals(componentName)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002602 services.add(r1);
2603 }
Amith Yamasani258848d2012-08-10 17:06:33 -07002604 } else if (name != null) {
2605 if (r1.name.flattenToString().contains(name)) {
2606 services.add(r1);
2607 }
2608 } else if (System.identityHashCode(r1) == objectId) {
2609 services.add(r1);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002610 }
2611 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002612 }
2613 }
2614 }
2615
2616 if (services.size() <= 0) {
2617 return false;
2618 }
2619
2620 boolean needSep = false;
2621 for (int i=0; i<services.size(); i++) {
2622 if (needSep) {
2623 pw.println();
2624 }
2625 needSep = true;
2626 dumpService("", fd, pw, services.get(i), args, dumpAll);
2627 }
2628 return true;
2629 }
2630
2631 /**
2632 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
2633 * there is a thread associated with the service.
2634 */
2635 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
2636 final ServiceRecord r, String[] args, boolean dumpAll) {
2637 String innerPrefix = prefix + " ";
2638 synchronized (this) {
2639 pw.print(prefix); pw.print("SERVICE ");
2640 pw.print(r.shortName); pw.print(" ");
2641 pw.print(Integer.toHexString(System.identityHashCode(r)));
2642 pw.print(" pid=");
2643 if (r.app != null) pw.println(r.app.pid);
2644 else pw.println("(not running)");
2645 if (dumpAll) {
2646 r.dump(pw, innerPrefix);
2647 }
2648 }
2649 if (r.app != null && r.app.thread != null) {
2650 pw.print(prefix); pw.println(" Client:");
2651 pw.flush();
2652 try {
2653 TransferPipe tp = new TransferPipe();
2654 try {
2655 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
2656 tp.setBufferPrefix(prefix + " ");
2657 tp.go(fd);
2658 } finally {
2659 tp.kill();
2660 }
2661 } catch (IOException e) {
2662 pw.println(prefix + " Failure while dumping the service: " + e);
2663 } catch (RemoteException e) {
2664 pw.println(prefix + " Got a RemoteException while dumping the service");
2665 }
2666 }
2667 }
2668
2669}