blob: be2df04dd20fd7ce79be79e54049991689137d5c [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 Hackborneaf2ac42014-02-07 13:01:07 -080031import com.android.internal.app.ProcessMap;
Dianne Hackbornd2932242013-08-05 18:18:42 -070032import com.android.internal.app.ProcessStats;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070033import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070034import com.android.internal.os.TransferPipe;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070035import com.android.server.am.ActivityManagerService.ItemMatcher;
36import com.android.server.am.ActivityManagerService.NeededUriGrants;
37
38import android.app.ActivityManager;
39import android.app.AppGlobals;
40import android.app.IApplicationThread;
41import android.app.IServiceConnection;
42import android.app.Notification;
43import android.app.PendingIntent;
44import android.app.Service;
45import android.content.ComponentName;
46import android.content.Context;
47import android.content.Intent;
48import android.content.pm.ApplicationInfo;
49import android.content.pm.PackageManager;
50import android.content.pm.ResolveInfo;
51import android.content.pm.ServiceInfo;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070052import android.os.Binder;
53import android.os.IBinder;
54import android.os.Message;
55import android.os.Process;
56import android.os.RemoteException;
57import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070058import android.os.UserHandle;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070059import android.util.EventLog;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070060import android.util.Slog;
61import android.util.SparseArray;
62import android.util.TimeUtils;
63
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -070064public final class ActiveServices {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070065 static final boolean DEBUG_SERVICE = ActivityManagerService.DEBUG_SERVICE;
66 static final boolean DEBUG_SERVICE_EXECUTING = ActivityManagerService.DEBUG_SERVICE_EXECUTING;
Dianne Hackborn9210bc82013-09-05 12:31:16 -070067 static final boolean DEBUG_DELAYED_SERVICE = ActivityManagerService.DEBUG_SERVICE;
Dianne Hackbornaa9875e2013-12-09 11:26:11 -080068 static final boolean DEBUG_DELAYED_STARTS = DEBUG_DELAYED_SERVICE;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070069 static final boolean DEBUG_MU = ActivityManagerService.DEBUG_MU;
70 static final String TAG = ActivityManagerService.TAG;
71 static final String TAG_MU = ActivityManagerService.TAG_MU;
72
73 // How long we wait for a service to finish executing.
74 static final int SERVICE_TIMEOUT = 20*1000;
75
Dianne Hackbornbf36ee22013-07-26 18:24:10 -070076 // How long we wait for a service to finish executing.
77 static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
78
Dianne Hackborn599db5c2012-08-03 19:28:48 -070079 // How long a service needs to be running until restarting its process
80 // is no longer considered to be a relaunch of the service.
Dianne Hackborn7b492722013-11-01 09:58:45 -070081 static final int SERVICE_RESTART_DURATION = 1*1000;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070082
83 // How long a service needs to be running until it will start back at
84 // SERVICE_RESTART_DURATION after being killed.
85 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
86
87 // Multiplying factor to increase restart duration time by, for each time
88 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
89 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
90
91 // The minimum amount of time between restarting services that we allow.
92 // That is, when multiple services are restarting, we won't allow each
93 // to restart less than this amount of time from the last one.
94 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
95
96 // Maximum amount of time for there to be no activity on a service before
97 // we consider it non-essential and allow its process to go on the
98 // LRU background list.
99 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
100
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700101 // How long we wait for a background started service to stop itself before
102 // allowing the next pending start to run.
103 static final int BG_START_TIMEOUT = 15*1000;
104
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700105 final ActivityManagerService mAm;
106
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700107 // Maximum number of services that we allow to start in the background
108 // at the same time.
109 final int mMaxStartingBackground;
110
111 final SparseArray<ServiceMap> mServiceMap = new SparseArray<ServiceMap>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700112
113 /**
114 * All currently bound service connections. Keys are the IBinder of
115 * the client's IServiceConnection.
116 */
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700117 final ArrayMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
118 = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700119
120 /**
121 * List of services that we have been asked to start,
122 * but haven't yet been able to. It is used to hold start requests
123 * while waiting for their corresponding application thread to get
124 * going.
125 */
126 final ArrayList<ServiceRecord> mPendingServices
127 = new ArrayList<ServiceRecord>();
128
129 /**
130 * List of services that are scheduled to restart following a crash.
131 */
132 final ArrayList<ServiceRecord> mRestartingServices
133 = new ArrayList<ServiceRecord>();
134
135 /**
Dianne Hackborn164371f2013-10-01 19:10:13 -0700136 * List of services that are in the process of being destroyed.
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700137 */
Dianne Hackborn164371f2013-10-01 19:10:13 -0700138 final ArrayList<ServiceRecord> mDestroyingServices
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700139 = new ArrayList<ServiceRecord>();
140
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700141 static final class DelayingProcess extends ArrayList<ServiceRecord> {
142 long timeoout;
143 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700144
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700145 /**
146 * Information about services for a single user.
147 */
148 class ServiceMap extends Handler {
Dianne Hackborn6285a322013-09-18 12:09:47 -0700149 final int mUserId;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700150 final ArrayMap<ComponentName, ServiceRecord> mServicesByName
151 = new ArrayMap<ComponentName, ServiceRecord>();
152 final ArrayMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent
153 = new ArrayMap<Intent.FilterComparison, ServiceRecord>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700154
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700155 final ArrayList<ServiceRecord> mDelayedStartList
156 = new ArrayList<ServiceRecord>();
157 /* XXX eventually I'd like to have this based on processes instead of services.
158 * That is, if we try to start two services in a row both running in the same
159 * process, this should be one entry in mStartingBackground for that one process
160 * that remains until all services in it are done.
161 final ArrayMap<ProcessRecord, DelayingProcess> mStartingBackgroundMap
162 = new ArrayMap<ProcessRecord, DelayingProcess>();
163 final ArrayList<DelayingProcess> mStartingProcessList
164 = new ArrayList<DelayingProcess>();
165 */
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700166
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700167 final ArrayList<ServiceRecord> mStartingBackground
168 = new ArrayList<ServiceRecord>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700169
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700170 static final int MSG_BG_START_TIMEOUT = 1;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700171
Dianne Hackborn13c590d2013-10-07 14:32:00 -0700172 ServiceMap(Looper looper, int userId) {
173 super(looper);
Dianne Hackborn6285a322013-09-18 12:09:47 -0700174 mUserId = userId;
175 }
176
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700177 @Override
178 public void handleMessage(Message msg) {
179 switch (msg.what) {
180 case MSG_BG_START_TIMEOUT: {
181 synchronized (mAm) {
182 rescheduleDelayedStarts();
183 }
184 } break;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700185 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700186 }
187
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700188 void ensureNotStartingBackground(ServiceRecord r) {
189 if (mStartingBackground.remove(r)) {
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800190 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "No longer background starting: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700191 rescheduleDelayedStarts();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700192 }
Dianne Hackborn2e46bb52013-09-13 17:01:26 -0700193 if (mDelayedStartList.remove(r)) {
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800194 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "No longer delaying start: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700195 }
196 }
197
198 void rescheduleDelayedStarts() {
199 removeMessages(MSG_BG_START_TIMEOUT);
200 final long now = SystemClock.uptimeMillis();
201 for (int i=0, N=mStartingBackground.size(); i<N; i++) {
202 ServiceRecord r = mStartingBackground.get(i);
203 if (r.startingBgTimeout <= now) {
204 Slog.i(TAG, "Waited long enough for: " + r);
205 mStartingBackground.remove(i);
206 N--;
207 }
208 }
209 while (mDelayedStartList.size() > 0
210 && mStartingBackground.size() < mMaxStartingBackground) {
211 ServiceRecord r = mDelayedStartList.remove(0);
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800212 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "REM FR DELAY LIST (exec next): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700213 if (r.pendingStarts.size() <= 0) {
214 Slog.w(TAG, "**** NO PENDING STARTS! " + r + " startReq=" + r.startRequested
215 + " delayedStop=" + r.delayedStop);
216 }
217 if (DEBUG_DELAYED_SERVICE) {
218 if (mDelayedStartList.size() > 0) {
219 Slog.v(TAG, "Remaining delayed list:");
220 for (int i=0; i<mDelayedStartList.size(); i++) {
221 Slog.v(TAG, " #" + i + ": " + mDelayedStartList.get(i));
222 }
223 }
224 }
225 r.delayed = false;
226 startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false, true);
227 }
228 if (mStartingBackground.size() > 0) {
229 ServiceRecord next = mStartingBackground.get(0);
230 long when = next.startingBgTimeout > now ? next.startingBgTimeout : now;
231 if (DEBUG_DELAYED_SERVICE) Slog.v(TAG, "Top bg start is " + next
232 + ", can delay others up to " + when);
233 Message msg = obtainMessage(MSG_BG_START_TIMEOUT);
234 sendMessageAtTime(msg, when);
235 }
Dianne Hackborn6285a322013-09-18 12:09:47 -0700236 if (mStartingBackground.size() < mMaxStartingBackground) {
237 mAm.backgroundServicesFinishedLocked(mUserId);
238 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700239 }
240 }
241
242 public ActiveServices(ActivityManagerService service) {
243 mAm = service;
Dianne Hackborn23037412013-11-04 18:11:29 -0800244 int maxBg = 0;
245 try {
246 maxBg = Integer.parseInt(SystemProperties.get("ro.config.max_starting_bg", "0"));
247 } catch(RuntimeException e) {
248 }
249 mMaxStartingBackground = maxBg > 0 ? maxBg : ActivityManager.isLowRamDeviceStatic() ? 1 : 3;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700250 }
251
252 ServiceRecord getServiceByName(ComponentName name, int callingUser) {
253 // TODO: Deal with global services
254 if (DEBUG_MU)
255 Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
256 return getServiceMap(callingUser).mServicesByName.get(name);
257 }
258
Dianne Hackborn6285a322013-09-18 12:09:47 -0700259 boolean hasBackgroundServices(int callingUser) {
260 ServiceMap smap = mServiceMap.get(callingUser);
261 return smap != null ? smap.mStartingBackground.size() >= mMaxStartingBackground : false;
262 }
263
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700264 private ServiceMap getServiceMap(int callingUser) {
265 ServiceMap smap = mServiceMap.get(callingUser);
266 if (smap == null) {
Dianne Hackborn13c590d2013-10-07 14:32:00 -0700267 smap = new ServiceMap(mAm.mHandler.getLooper(), callingUser);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700268 mServiceMap.put(callingUser, smap);
269 }
270 return smap;
271 }
272
273 ArrayMap<ComponentName, ServiceRecord> getServices(int callingUser) {
274 return getServiceMap(callingUser).mServicesByName;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700275 }
276
277 ComponentName startServiceLocked(IApplicationThread caller,
278 Intent service, String resolvedType,
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700279 int callingPid, int callingUid, int userId) {
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800280 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "startService: " + service
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700281 + " type=" + resolvedType + " args=" + service.getExtras());
282
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700283 final boolean callerFg;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700284 if (caller != null) {
285 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
286 if (callerApp == null) {
287 throw new SecurityException(
288 "Unable to find app for caller " + caller
289 + " (pid=" + Binder.getCallingPid()
290 + ") when starting service " + service);
291 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700292 callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
293 } else {
294 callerFg = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700295 }
296
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700297
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700298 ServiceLookupResult res =
299 retrieveServiceLocked(service, resolvedType,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700300 callingPid, callingUid, userId, true, callerFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700301 if (res == null) {
302 return null;
303 }
304 if (res.record == null) {
305 return new ComponentName("!", res.permission != null
306 ? res.permission : "private to package");
307 }
308 ServiceRecord r = res.record;
309 NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
310 callingUid, r.packageName, service, service.getFlags(), null);
Dianne Hackbornd6f5b622013-11-11 17:25:37 -0800311 if (unscheduleServiceRestartLocked(r, callingUid, false)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700312 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
313 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700314 r.lastActivity = SystemClock.uptimeMillis();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700315 r.startRequested = true;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700316 r.delayedStop = false;
317 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
318 service, neededGrants));
319
320 final ServiceMap smap = getServiceMap(r.userId);
321 boolean addToStarting = false;
322 if (!callerFg && r.app == null && mAm.mStartedUsers.get(r.userId) != null) {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700323 ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700324 if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700325 // If this is not coming from a foreground caller, then we may want
326 // to delay the start if there are already other background services
327 // that are starting. This is to avoid process start spam when lots
328 // of applications are all handling things like connectivity broadcasts.
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700329 // We only do this for cached processes, because otherwise an application
330 // can have assumptions about calling startService() for a service to run
331 // in its own process, and for that process to not be killed before the
332 // service is started. This is especially the case for receivers, which
333 // may start a service in onReceive() to do some additional work and have
334 // initialized some global state as part of that.
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700335 if (DEBUG_DELAYED_SERVICE) Slog.v(TAG, "Potential start delay of " + r + " in "
336 + proc);
337 if (r.delayed) {
338 // This service is already scheduled for a delayed start; just leave
339 // it still waiting.
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800340 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Continuing to delay: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700341 return r.name;
342 }
343 if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
344 // Something else is starting, delay!
345 Slog.i(TAG, "Delaying start of: " + r);
346 smap.mDelayedStartList.add(r);
347 r.delayed = true;
348 return r.name;
349 }
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800350 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Not delaying: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700351 addToStarting = true;
352 } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
353 // We slightly loosen when we will enqueue this new service as a background
354 // starting service we are waiting for, to also include processes that are
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700355 // currently running other services or receivers.
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700356 addToStarting = true;
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800357 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Not delaying, but counting as bg: " + r);
358 } else if (DEBUG_DELAYED_STARTS) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700359 StringBuilder sb = new StringBuilder(128);
360 sb.append("Not potential delay (state=").append(proc.curProcState)
361 .append(' ').append(proc.adjType);
362 String reason = proc.makeAdjReason();
363 if (reason != null) {
364 sb.append(' ');
365 sb.append(reason);
366 }
367 sb.append("): ");
368 sb.append(r.toString());
369 Slog.v(TAG, sb.toString());
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700370 }
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800371 } else if (DEBUG_DELAYED_STARTS) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700372 if (callerFg) {
373 Slog.v(TAG, "Not potential delay (callerFg=" + callerFg + " uid="
374 + callingUid + " pid=" + callingPid + "): " + r);
375 } else if (r.app != null) {
376 Slog.v(TAG, "Not potential delay (cur app=" + r.app + "): " + r);
377 } else {
378 Slog.v(TAG, "Not potential delay (user " + r.userId + " not started): " + r);
379 }
380 }
381
382 return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
383 }
384
385 ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
386 ServiceRecord r, boolean callerFg, boolean addToStarting) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700387 ProcessStats.ServiceState stracker = r.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -0700388 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700389 stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700390 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700391 r.callStart = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700392 synchronized (r.stats.getBatteryStats()) {
393 r.stats.startRunningLocked();
394 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700395 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -0700396 if (error != null) {
397 return new ComponentName("!!", error);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700398 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700399
400 if (r.startRequested && addToStarting) {
401 boolean first = smap.mStartingBackground.size() == 0;
402 smap.mStartingBackground.add(r);
403 r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
404 if (DEBUG_DELAYED_SERVICE) {
405 RuntimeException here = new RuntimeException("here");
406 here.fillInStackTrace();
407 Slog.v(TAG, "Starting background (first=" + first + "): " + r, here);
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800408 } else if (DEBUG_DELAYED_STARTS) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700409 Slog.v(TAG, "Starting background (first=" + first + "): " + r);
410 }
411 if (first) {
412 smap.rescheduleDelayedStarts();
413 }
414 } else if (callerFg) {
415 smap.ensureNotStartingBackground(r);
416 }
417
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700418 return r.name;
419 }
420
421 private void stopServiceLocked(ServiceRecord service) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700422 if (service.delayed) {
423 // If service isn't actually running, but is is being held in the
424 // delayed list, then we need to keep it started but note that it
425 // should be stopped once no longer delayed.
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800426 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Delaying stop of pending: " + service);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700427 service.delayedStop = true;
428 return;
429 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700430 synchronized (service.stats.getBatteryStats()) {
431 service.stats.stopRunningLocked();
432 }
433 service.startRequested = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700434 if (service.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700435 service.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700436 SystemClock.uptimeMillis());
437 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700438 service.callStart = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700439 bringDownServiceIfNeededLocked(service, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700440 }
441
442 int stopServiceLocked(IApplicationThread caller, Intent service,
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700443 String resolvedType, int userId) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700444 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
445 + " type=" + resolvedType);
446
447 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
448 if (caller != null && callerApp == null) {
449 throw new SecurityException(
450 "Unable to find app for caller " + caller
451 + " (pid=" + Binder.getCallingPid()
452 + ") when stopping service " + service);
453 }
454
455 // If this service is active, make sure it is stopped.
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -0700456 ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700457 Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700458 if (r != null) {
459 if (r.record != null) {
460 final long origId = Binder.clearCallingIdentity();
461 try {
462 stopServiceLocked(r.record);
463 } finally {
464 Binder.restoreCallingIdentity(origId);
465 }
466 return 1;
467 }
468 return -1;
469 }
470
471 return 0;
472 }
473
474 IBinder peekServiceLocked(Intent service, String resolvedType) {
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -0700475 ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
476 Binder.getCallingPid(), Binder.getCallingUid(),
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700477 UserHandle.getCallingUserId(), false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700478
479 IBinder ret = null;
480 if (r != null) {
481 // r.record is null if findServiceLocked() failed the caller permission check
482 if (r.record == null) {
483 throw new SecurityException(
484 "Permission Denial: Accessing service " + r.record.name
485 + " from pid=" + Binder.getCallingPid()
486 + ", uid=" + Binder.getCallingUid()
487 + " requires " + r.permission);
488 }
489 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
490 if (ib != null) {
491 ret = ib.binder;
492 }
493 }
494
495 return ret;
496 }
497
498 boolean stopServiceTokenLocked(ComponentName className, IBinder token,
499 int startId) {
500 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
501 + " " + token + " startId=" + startId);
Dianne Hackborn41203752012-08-31 14:05:51 -0700502 ServiceRecord r = findServiceLocked(className, token, UserHandle.getCallingUserId());
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700503 if (r != null) {
504 if (startId >= 0) {
505 // Asked to only stop if done with all work. Note that
506 // to avoid leaks, we will take this as dropping all
507 // start items up to and including this one.
508 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
509 if (si != null) {
510 while (r.deliveredStarts.size() > 0) {
511 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
512 cur.removeUriPermissionsLocked();
513 if (cur == si) {
514 break;
515 }
516 }
517 }
518
519 if (r.getLastStartId() != startId) {
520 return false;
521 }
522
523 if (r.deliveredStarts.size() > 0) {
524 Slog.w(TAG, "stopServiceToken startId " + startId
525 + " is last, but have " + r.deliveredStarts.size()
526 + " remaining args");
527 }
528 }
529
530 synchronized (r.stats.getBatteryStats()) {
531 r.stats.stopRunningLocked();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700532 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700533 r.startRequested = false;
534 if (r.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700535 r.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700536 SystemClock.uptimeMillis());
537 }
538 r.callStart = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700539 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700540 bringDownServiceIfNeededLocked(r, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700541 Binder.restoreCallingIdentity(origId);
542 return true;
543 }
544 return false;
545 }
546
547 public void setServiceForegroundLocked(ComponentName className, IBinder token,
548 int id, Notification notification, boolean removeNotification) {
Dianne Hackborn41203752012-08-31 14:05:51 -0700549 final int userId = UserHandle.getCallingUserId();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700550 final long origId = Binder.clearCallingIdentity();
551 try {
Dianne Hackborn41203752012-08-31 14:05:51 -0700552 ServiceRecord r = findServiceLocked(className, token, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700553 if (r != null) {
554 if (id != 0) {
555 if (notification == null) {
556 throw new IllegalArgumentException("null notification");
557 }
558 if (r.foregroundId != id) {
559 r.cancelNotification();
560 r.foregroundId = id;
561 }
562 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
563 r.foregroundNoti = notification;
564 r.isForeground = true;
565 r.postNotification();
566 if (r.app != null) {
567 updateServiceForegroundLocked(r.app, true);
568 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700569 getServiceMap(r.userId).ensureNotStartingBackground(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700570 } else {
571 if (r.isForeground) {
572 r.isForeground = false;
573 if (r.app != null) {
Dianne Hackborndb926082013-10-31 16:32:44 -0700574 mAm.updateLruProcessLocked(r.app, false, null);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700575 updateServiceForegroundLocked(r.app, true);
576 }
577 }
578 if (removeNotification) {
579 r.cancelNotification();
580 r.foregroundId = 0;
581 r.foregroundNoti = null;
582 }
583 }
584 }
585 } finally {
586 Binder.restoreCallingIdentity(origId);
587 }
588 }
589
590 private void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
591 boolean anyForeground = false;
Dianne Hackbornc8230512013-07-13 21:32:12 -0700592 for (int i=proc.services.size()-1; i>=0; i--) {
593 ServiceRecord sr = proc.services.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700594 if (sr.isForeground) {
595 anyForeground = true;
596 break;
597 }
598 }
Dianne Hackborneaf2ac42014-02-07 13:01:07 -0800599 mAm.updateProcessForegroundLocked(proc, anyForeground, oomAdj);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700600 }
601
Dianne Hackborndb926082013-10-31 16:32:44 -0700602 private boolean updateServiceClientActivitiesLocked(ProcessRecord proc,
603 ConnectionRecord modCr) {
604 if (modCr != null && modCr.binding.client != null) {
605 if (modCr.binding.client.activities.size() <= 0) {
606 // This connection is from a client without activities, so adding
607 // and removing is not interesting.
608 return false;
609 }
610 }
611
612 boolean anyClientActivities = false;
613 for (int i=proc.services.size()-1; i>=0 && !anyClientActivities; i--) {
614 ServiceRecord sr = proc.services.valueAt(i);
615 for (int conni=sr.connections.size()-1; conni>=0 && !anyClientActivities; conni--) {
616 ArrayList<ConnectionRecord> clist = sr.connections.valueAt(conni);
617 for (int cri=clist.size()-1; cri>=0; cri--) {
618 ConnectionRecord cr = clist.get(cri);
619 if (cr.binding.client == null || cr.binding.client == proc) {
620 // Binding to ourself is not interesting.
621 continue;
622 }
623 if (cr.binding.client.activities.size() > 0) {
624 anyClientActivities = true;
625 break;
626 }
627 }
628 }
629 }
630 if (anyClientActivities != proc.hasClientActivities) {
631 proc.hasClientActivities = anyClientActivities;
632 mAm.updateLruProcessLocked(proc, anyClientActivities, null);
633 return true;
634 }
635 return false;
636 }
637
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700638 int bindServiceLocked(IApplicationThread caller, IBinder token,
639 Intent service, String resolvedType,
640 IServiceConnection connection, int flags, int userId) {
641 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
642 + " type=" + resolvedType + " conn=" + connection.asBinder()
643 + " flags=0x" + Integer.toHexString(flags));
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700644 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
645 if (callerApp == null) {
646 throw new SecurityException(
647 "Unable to find app for caller " + caller
648 + " (pid=" + Binder.getCallingPid()
649 + ") when binding service " + service);
650 }
651
652 ActivityRecord activity = null;
653 if (token != null) {
Craig Mautnerd2328952013-03-05 12:46:26 -0800654 activity = ActivityRecord.isInStackLocked(token);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700655 if (activity == null) {
656 Slog.w(TAG, "Binding with unknown activity: " + token);
657 return 0;
658 }
659 }
660
661 int clientLabel = 0;
662 PendingIntent clientIntent = null;
663
664 if (callerApp.info.uid == Process.SYSTEM_UID) {
665 // Hacky kind of thing -- allow system stuff to tell us
666 // what they are, so we can report this elsewhere for
667 // others to know why certain services are running.
668 try {
669 clientIntent = (PendingIntent)service.getParcelableExtra(
670 Intent.EXTRA_CLIENT_INTENT);
671 } catch (RuntimeException e) {
672 }
673 if (clientIntent != null) {
674 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
675 if (clientLabel != 0) {
676 // There are no useful extras in the intent, trash them.
677 // System code calling with this stuff just needs to know
678 // this will happen.
679 service = service.cloneFilter();
680 }
681 }
682 }
683
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700684 final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
685
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700686 ServiceLookupResult res =
687 retrieveServiceLocked(service, resolvedType,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700688 Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700689 if (res == null) {
690 return 0;
691 }
692 if (res.record == null) {
693 return -1;
694 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700695 ServiceRecord s = res.record;
696
697 final long origId = Binder.clearCallingIdentity();
698
699 try {
Dianne Hackbornd6f5b622013-11-11 17:25:37 -0800700 if (unscheduleServiceRestartLocked(s, callerApp.info.uid, false)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700701 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
702 + s);
703 }
704
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700705 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
706 s.lastActivity = SystemClock.uptimeMillis();
707 if (!s.hasAutoCreateConnections()) {
708 // This is the first binding, let the tracker know.
Dianne Hackbornd2932242013-08-05 18:18:42 -0700709 ProcessStats.ServiceState stracker = s.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -0700710 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700711 stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700712 s.lastActivity);
713 }
714 }
715 }
716
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700717 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
718 ConnectionRecord c = new ConnectionRecord(b, activity,
719 connection, flags, clientLabel, clientIntent);
720
721 IBinder binder = connection.asBinder();
722 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
723 if (clist == null) {
724 clist = new ArrayList<ConnectionRecord>();
725 s.connections.put(binder, clist);
726 }
727 clist.add(c);
728 b.connections.add(c);
729 if (activity != null) {
730 if (activity.connections == null) {
731 activity.connections = new HashSet<ConnectionRecord>();
732 }
733 activity.connections.add(c);
734 }
735 b.client.connections.add(c);
736 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
737 b.client.hasAboveClient = true;
738 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700739 if (s.app != null) {
740 updateServiceClientActivitiesLocked(s.app, c);
741 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700742 clist = mServiceConnections.get(binder);
743 if (clist == null) {
744 clist = new ArrayList<ConnectionRecord>();
745 mServiceConnections.put(binder, clist);
746 }
747 clist.add(c);
748
749 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
750 s.lastActivity = SystemClock.uptimeMillis();
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700751 if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700752 return 0;
753 }
754 }
755
756 if (s.app != null) {
757 // This could have made the service more important.
Dianne Hackborndb926082013-10-31 16:32:44 -0700758 mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities, b.client);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700759 mAm.updateOomAdjLocked(s.app);
760 }
761
762 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
763 + ": received=" + b.intent.received
764 + " apps=" + b.intent.apps.size()
765 + " doRebind=" + b.intent.doRebind);
766
767 if (s.app != null && b.intent.received) {
768 // Service is already running, so we can immediately
769 // publish the connection.
770 try {
771 c.conn.connected(s.name, b.intent.binder);
772 } catch (Exception e) {
773 Slog.w(TAG, "Failure sending service " + s.shortName
774 + " to connection " + c.conn.asBinder()
775 + " (in " + c.binding.client.processName + ")", e);
776 }
777
778 // If this is the first app connected back to this binding,
779 // and the service had previously asked to be told when
780 // rebound, then do so.
781 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700782 requestServiceBindingLocked(s, b.intent, callerFg, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700783 }
784 } else if (!b.intent.requested) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700785 requestServiceBindingLocked(s, b.intent, callerFg, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700786 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700787
788 getServiceMap(s.userId).ensureNotStartingBackground(s);
789
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700790 } finally {
791 Binder.restoreCallingIdentity(origId);
792 }
793
794 return 1;
795 }
796
797 void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
798 final long origId = Binder.clearCallingIdentity();
799 try {
800 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
801 + " " + intent + ": " + service);
802 if (r != null) {
803 Intent.FilterComparison filter
804 = new Intent.FilterComparison(intent);
805 IntentBindRecord b = r.bindings.get(filter);
806 if (b != null && !b.received) {
807 b.binder = service;
808 b.requested = true;
809 b.received = true;
Dianne Hackborn390517b2013-05-30 15:03:32 -0700810 for (int conni=r.connections.size()-1; conni>=0; conni--) {
811 ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
812 for (int i=0; i<clist.size(); i++) {
813 ConnectionRecord c = clist.get(i);
814 if (!filter.equals(c.binding.intent.intent)) {
815 if (DEBUG_SERVICE) Slog.v(
816 TAG, "Not publishing to: " + c);
817 if (DEBUG_SERVICE) Slog.v(
818 TAG, "Bound intent: " + c.binding.intent.intent);
819 if (DEBUG_SERVICE) Slog.v(
820 TAG, "Published intent: " + intent);
821 continue;
822 }
823 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
824 try {
825 c.conn.connected(r.name, service);
826 } catch (Exception e) {
827 Slog.w(TAG, "Failure sending service " + r.name +
828 " to connection " + c.conn.asBinder() +
829 " (in " + c.binding.client.processName + ")", e);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700830 }
831 }
832 }
833 }
834
Dianne Hackborn164371f2013-10-01 19:10:13 -0700835 serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700836 }
837 } finally {
838 Binder.restoreCallingIdentity(origId);
839 }
840 }
841
842 boolean unbindServiceLocked(IServiceConnection connection) {
843 IBinder binder = connection.asBinder();
844 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
845 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
846 if (clist == null) {
847 Slog.w(TAG, "Unbind failed: could not find connection for "
848 + connection.asBinder());
849 return false;
850 }
851
852 final long origId = Binder.clearCallingIdentity();
853 try {
854 while (clist.size() > 0) {
855 ConnectionRecord r = clist.get(0);
856 removeConnectionLocked(r, null, null);
857
858 if (r.binding.service.app != null) {
859 // This could have made the service less important.
860 mAm.updateOomAdjLocked(r.binding.service.app);
861 }
862 }
863 } finally {
864 Binder.restoreCallingIdentity(origId);
865 }
866
867 return true;
868 }
869
870 void unbindFinishedLocked(ServiceRecord r, Intent intent, boolean doRebind) {
871 final long origId = Binder.clearCallingIdentity();
872 try {
873 if (r != null) {
874 Intent.FilterComparison filter
875 = new Intent.FilterComparison(intent);
876 IntentBindRecord b = r.bindings.get(filter);
877 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
878 + " at " + b + ": apps="
879 + (b != null ? b.apps.size() : 0));
880
Dianne Hackborn164371f2013-10-01 19:10:13 -0700881 boolean inDestroying = mDestroyingServices.contains(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700882 if (b != null) {
Dianne Hackborn164371f2013-10-01 19:10:13 -0700883 if (b.apps.size() > 0 && !inDestroying) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700884 // Applications have already bound since the last
885 // unbind, so just rebind right here.
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700886 boolean inFg = false;
887 for (int i=b.apps.size()-1; i>=0; i--) {
888 ProcessRecord client = b.apps.valueAt(i).client;
889 if (client != null && client.setSchedGroup
890 != Process.THREAD_GROUP_BG_NONINTERACTIVE) {
891 inFg = true;
892 break;
893 }
894 }
895 requestServiceBindingLocked(r, b, inFg, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700896 } else {
897 // Note to tell the service the next time there is
898 // a new client.
899 b.doRebind = true;
900 }
901 }
902
Dianne Hackborn164371f2013-10-01 19:10:13 -0700903 serviceDoneExecutingLocked(r, inDestroying, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700904 }
905 } finally {
906 Binder.restoreCallingIdentity(origId);
907 }
908 }
909
910 private final ServiceRecord findServiceLocked(ComponentName name,
Dianne Hackborn41203752012-08-31 14:05:51 -0700911 IBinder token, int userId) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700912 ServiceRecord r = getServiceByName(name, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700913 return r == token ? r : null;
914 }
915
916 private final class ServiceLookupResult {
917 final ServiceRecord record;
918 final String permission;
919
920 ServiceLookupResult(ServiceRecord _record, String _permission) {
921 record = _record;
922 permission = _permission;
923 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700924 }
925
926 private class ServiceRestarter implements Runnable {
927 private ServiceRecord mService;
928
929 void setService(ServiceRecord service) {
930 mService = service;
931 }
932
933 public void run() {
934 synchronized(mAm) {
935 performServiceRestartLocked(mService);
936 }
937 }
938 }
939
940 private ServiceLookupResult retrieveServiceLocked(Intent service,
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -0700941 String resolvedType, int callingPid, int callingUid, int userId,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700942 boolean createIfNeeded, boolean callingFromFg) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700943 ServiceRecord r = null;
944 if (DEBUG_SERVICE) Slog.v(TAG, "retrieveServiceLocked: " + service
945 + " type=" + resolvedType + " callingUid=" + callingUid);
946
Dianne Hackborn139748f2012-09-24 11:36:57 -0700947 userId = mAm.handleIncomingUser(callingPid, callingUid, userId,
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700948 false, true, "service", null);
949
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700950 ServiceMap smap = getServiceMap(userId);
951 final ComponentName comp = service.getComponent();
952 if (comp != null) {
953 r = smap.mServicesByName.get(comp);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700954 }
955 if (r == null) {
956 Intent.FilterComparison filter = new Intent.FilterComparison(service);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700957 r = smap.mServicesByIntent.get(filter);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700958 }
959 if (r == null) {
960 try {
961 ResolveInfo rInfo =
962 AppGlobals.getPackageManager().resolveService(
963 service, resolvedType,
964 ActivityManagerService.STOCK_PM_FLAGS, userId);
965 ServiceInfo sInfo =
966 rInfo != null ? rInfo.serviceInfo : null;
967 if (sInfo == null) {
Amith Yamasani2b914652012-08-27 12:04:40 -0700968 Slog.w(TAG, "Unable to start service " + service + " U=" + userId +
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700969 ": not found");
970 return null;
971 }
972 ComponentName name = new ComponentName(
973 sInfo.applicationInfo.packageName, sInfo.name);
974 if (userId > 0) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700975 if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
976 sInfo.name, sInfo.flags)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700977 userId = 0;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700978 smap = getServiceMap(0);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700979 }
980 sInfo = new ServiceInfo(sInfo);
981 sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
982 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700983 r = smap.mServicesByName.get(name);
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -0700984 if (r == null && createIfNeeded) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700985 Intent.FilterComparison filter
986 = new Intent.FilterComparison(service.cloneFilter());
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700987 ServiceRestarter res = new ServiceRestarter();
988 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
989 BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics();
990 synchronized (stats) {
991 ss = stats.getServiceStatsLocked(
992 sInfo.applicationInfo.uid, sInfo.packageName,
993 sInfo.name);
994 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700995 r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700996 res.setService(r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700997 smap.mServicesByName.put(name, r);
998 smap.mServicesByIntent.put(filter, r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700999
1000 // Make sure this component isn't in the pending list.
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001001 for (int i=mPendingServices.size()-1; i>=0; i--) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001002 ServiceRecord pr = mPendingServices.get(i);
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001003 if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
1004 && pr.name.equals(name)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001005 mPendingServices.remove(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001006 }
1007 }
1008 }
1009 } catch (RemoteException ex) {
1010 // pm is in same process, this will never happen.
1011 }
1012 }
1013 if (r != null) {
1014 if (mAm.checkComponentPermission(r.permission,
1015 callingPid, callingUid, r.appInfo.uid, r.exported)
1016 != PackageManager.PERMISSION_GRANTED) {
1017 if (!r.exported) {
1018 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
1019 + " from pid=" + callingPid
1020 + ", uid=" + callingUid
1021 + " that is not exported from uid " + r.appInfo.uid);
1022 return new ServiceLookupResult(null, "not exported from uid "
1023 + r.appInfo.uid);
1024 }
1025 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
1026 + " from pid=" + callingPid
1027 + ", uid=" + callingUid
1028 + " requires " + r.permission);
1029 return new ServiceLookupResult(null, r.permission);
1030 }
Ben Gruverf5323fe2013-07-31 15:09:51 -07001031 if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
1032 resolvedType, r.appInfo)) {
Ben Gruverb6223792013-07-29 16:35:40 -07001033 return null;
1034 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001035 return new ServiceLookupResult(r, null);
1036 }
1037 return null;
1038 }
1039
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001040 private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001041 if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001042 + why + " of " + r + " in app " + r.app);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001043 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, ">>> EXECUTING "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001044 + why + " of " + r.shortName);
1045 long now = SystemClock.uptimeMillis();
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001046 if (r.executeNesting == 0) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001047 r.executeFg = fg;
Dianne Hackbornd2932242013-08-05 18:18:42 -07001048 ProcessStats.ServiceState stracker = r.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001049 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001050 stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001051 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001052 if (r.app != null) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001053 r.app.executingServices.add(r);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001054 r.app.execServicesFg |= fg;
Dianne Hackborn2be00932013-09-22 16:46:00 -07001055 if (r.app.executingServices.size() == 1) {
1056 scheduleServiceTimeoutLocked(r.app);
1057 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001058 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001059 } else if (r.app != null && fg && !r.app.execServicesFg) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001060 r.app.execServicesFg = true;
Dianne Hackborn2be00932013-09-22 16:46:00 -07001061 scheduleServiceTimeoutLocked(r.app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001062 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001063 r.executeFg |= fg;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001064 r.executeNesting++;
1065 r.executingStart = now;
1066 }
1067
1068 private final boolean requestServiceBindingLocked(ServiceRecord r,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001069 IntentBindRecord i, boolean execInFg, boolean rebind) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001070 if (r.app == null || r.app.thread == null) {
1071 // If service is not currently running, can't yet bind.
1072 return false;
1073 }
1074 if ((!i.requested || rebind) && i.apps.size() > 0) {
1075 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001076 bumpServiceExecutingLocked(r, execInFg, "bind");
Dianne Hackborna413dc02013-07-12 12:02:55 -07001077 r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
1078 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
1079 r.app.repProcState);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001080 if (!rebind) {
1081 i.requested = true;
1082 }
1083 i.hasBound = true;
1084 i.doRebind = false;
1085 } catch (RemoteException e) {
1086 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
1087 return false;
1088 }
1089 }
1090 return true;
1091 }
1092
1093 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
1094 boolean allowCancel) {
1095 boolean canceled = false;
1096
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001097 ServiceMap smap = getServiceMap(r.userId);
1098 if (smap.mServicesByName.get(r.name) != r) {
1099 ServiceRecord cur = smap.mServicesByName.get(r.name);
1100 Slog.wtf(TAG, "Attempting to schedule restart of " + r
1101 + " when found in map: " + cur);
1102 return false;
1103 }
1104
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001105 final long now = SystemClock.uptimeMillis();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001106
1107 if ((r.serviceInfo.applicationInfo.flags
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001108 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
1109 long minDuration = SERVICE_RESTART_DURATION;
1110 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001111
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001112 // Any delivered but not yet finished starts should be put back
1113 // on the pending list.
1114 final int N = r.deliveredStarts.size();
1115 if (N > 0) {
1116 for (int i=N-1; i>=0; i--) {
1117 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
1118 si.removeUriPermissionsLocked();
1119 if (si.intent == null) {
1120 // We'll generate this again if needed.
1121 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
1122 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
1123 r.pendingStarts.add(0, si);
1124 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
1125 dur *= 2;
1126 if (minDuration < dur) minDuration = dur;
1127 if (resetTime < dur) resetTime = dur;
1128 } else {
1129 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
1130 + r.name);
1131 canceled = true;
1132 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001133 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001134 r.deliveredStarts.clear();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001135 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001136
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001137 r.totalRestartCount++;
1138 if (r.restartDelay == 0) {
1139 r.restartCount++;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001140 r.restartDelay = minDuration;
1141 } else {
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001142 // If it has been a "reasonably long time" since the service
1143 // was started, then reset our restart duration back to
1144 // the beginning, so we don't infinitely increase the duration
1145 // on a service that just occasionally gets killed (which is
1146 // a normal case, due to process being killed to reclaim memory).
1147 if (now > (r.restartTime+resetTime)) {
1148 r.restartCount = 1;
1149 r.restartDelay = minDuration;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001150 } else {
Dianne Hackborn7b492722013-11-01 09:58:45 -07001151 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
1152 if (r.restartDelay < minDuration) {
1153 r.restartDelay = minDuration;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001154 }
1155 }
1156 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001157
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001158 r.nextRestartTime = now + r.restartDelay;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001159
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001160 // Make sure that we don't end up restarting a bunch of services
1161 // all at the same time.
1162 boolean repeat;
1163 do {
1164 repeat = false;
1165 for (int i=mRestartingServices.size()-1; i>=0; i--) {
1166 ServiceRecord r2 = mRestartingServices.get(i);
1167 if (r2 != r && r.nextRestartTime
1168 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
1169 && r.nextRestartTime
1170 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
1171 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
1172 r.restartDelay = r.nextRestartTime - now;
1173 repeat = true;
1174 break;
1175 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001176 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001177 } while (repeat);
1178
1179 } else {
Dianne Hackborn7b492722013-11-01 09:58:45 -07001180 // Persistent processes are immediately restarted, so there is no
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001181 // reason to hold of on restarting their services.
1182 r.totalRestartCount++;
1183 r.restartCount = 0;
1184 r.restartDelay = 0;
1185 r.nextRestartTime = now;
1186 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001187
1188 if (!mRestartingServices.contains(r)) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001189 r.createdFromFg = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001190 mRestartingServices.add(r);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001191 r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001192 }
1193
1194 r.cancelNotification();
1195
1196 mAm.mHandler.removeCallbacks(r.restarter);
1197 mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime);
1198 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
1199 Slog.w(TAG, "Scheduling restart of crashed service "
1200 + r.shortName + " in " + r.restartDelay + "ms");
1201 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001202 r.userId, r.shortName, r.restartDelay);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001203
1204 return canceled;
1205 }
1206
1207 final void performServiceRestartLocked(ServiceRecord r) {
1208 if (!mRestartingServices.contains(r)) {
1209 return;
1210 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001211 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001212 }
1213
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001214 private final boolean unscheduleServiceRestartLocked(ServiceRecord r, int callingUid,
1215 boolean force) {
1216 if (!force && r.restartDelay == 0) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001217 return false;
1218 }
Dianne Hackborn7b492722013-11-01 09:58:45 -07001219 // Remove from the restarting list; if the service is currently on the
1220 // restarting list, or the call is coming from another app, then this
1221 // service has become of much more interest so we reset the restart interval.
1222 boolean removed = mRestartingServices.remove(r);
1223 if (removed || callingUid != r.appInfo.uid) {
1224 r.resetRestartCounter();
1225 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001226 if (removed) {
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001227 clearRestartingIfNeededLocked(r);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001228 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001229 mAm.mHandler.removeCallbacks(r.restarter);
1230 return true;
1231 }
1232
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001233 private void clearRestartingIfNeededLocked(ServiceRecord r) {
1234 if (r.restartTracker != null) {
1235 // If this is the last restarting record with this tracker, then clear
1236 // the tracker's restarting state.
1237 boolean stillTracking = false;
1238 for (int i=mRestartingServices.size()-1; i>=0; i--) {
1239 if (mRestartingServices.get(i).restartTracker == r.restartTracker) {
1240 stillTracking = true;
1241 break;
1242 }
1243 }
1244 if (!stillTracking) {
1245 r.restartTracker.setRestarting(false, mAm.mProcessStats.getMemFactorLocked(),
1246 SystemClock.uptimeMillis());
1247 r.restartTracker = null;
1248 }
1249 }
1250 }
1251
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001252 private final String bringUpServiceLocked(ServiceRecord r,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001253 int intentFlags, boolean execInFg, boolean whileRestarting) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001254 //Slog.i(TAG, "Bring up service:");
1255 //r.dump(" ");
1256
1257 if (r.app != null && r.app.thread != null) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001258 sendServiceArgsLocked(r, execInFg, false);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001259 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001260 }
1261
1262 if (!whileRestarting && r.restartDelay > 0) {
1263 // If waiting for a restart, then do nothing.
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001264 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001265 }
1266
1267 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
1268
1269 // We are now bringing the service up, so no longer in the
1270 // restarting state.
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001271 if (mRestartingServices.remove(r)) {
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001272 clearRestartingIfNeededLocked(r);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001273 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001274
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001275 // Make sure this service is no longer considered delayed, we are starting it now.
1276 if (r.delayed) {
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08001277 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "REM FR DELAY LIST (bring up): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001278 getServiceMap(r.userId).mDelayedStartList.remove(r);
1279 r.delayed = false;
1280 }
1281
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001282 // Make sure that the user who owns this service is started. If not,
1283 // we don't want to allow it to run.
1284 if (mAm.mStartedUsers.get(r.userId) == null) {
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001285 String msg = "Unable to launch app "
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001286 + r.appInfo.packageName + "/"
1287 + r.appInfo.uid + " for service "
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001288 + r.intent.getIntent() + ": user " + r.userId + " is stopped";
1289 Slog.w(TAG, msg);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001290 bringDownServiceLocked(r);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001291 return msg;
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001292 }
1293
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001294 // Service is now being launched, its package can't be stopped.
1295 try {
1296 AppGlobals.getPackageManager().setPackageStoppedState(
1297 r.packageName, false, r.userId);
1298 } catch (RemoteException e) {
1299 } catch (IllegalArgumentException e) {
1300 Slog.w(TAG, "Failed trying to unstop package "
1301 + r.packageName + ": " + e);
1302 }
1303
1304 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
1305 final String procName = r.processName;
1306 ProcessRecord app;
1307
1308 if (!isolated) {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001309 app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
1310 if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
1311 + " app=" + app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001312 if (app != null && app.thread != null) {
1313 try {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001314 app.addPackage(r.appInfo.packageName, mAm.mProcessStats);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001315 realStartServiceLocked(r, app, execInFg);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001316 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001317 } catch (RemoteException e) {
1318 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
1319 }
1320
1321 // If a dead object exception was thrown -- fall through to
1322 // restart the application.
1323 }
1324 } else {
1325 // If this service runs in an isolated process, then each time
1326 // we call startProcessLocked() we will get a new isolated
1327 // process, starting another process if we are currently waiting
1328 // for a previous process to come up. To deal with this, we store
1329 // in the service any current isolated process it is running in or
1330 // waiting to have come up.
1331 app = r.isolatedProc;
1332 }
1333
1334 // Not running -- get it started, and enqueue this service record
1335 // to be executed when the app comes up.
1336 if (app == null) {
1337 if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001338 "service", r.name, false, isolated, false)) == null) {
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001339 String msg = "Unable to launch app "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001340 + r.appInfo.packageName + "/"
1341 + r.appInfo.uid + " for service "
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001342 + r.intent.getIntent() + ": process is bad";
1343 Slog.w(TAG, msg);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001344 bringDownServiceLocked(r);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001345 return msg;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001346 }
1347 if (isolated) {
1348 r.isolatedProc = app;
1349 }
1350 }
1351
1352 if (!mPendingServices.contains(r)) {
1353 mPendingServices.add(r);
1354 }
1355
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001356 if (r.delayedStop) {
1357 // Oh and hey we've already been asked to stop!
1358 r.delayedStop = false;
1359 if (r.startRequested) {
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08001360 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Applying delayed stop (in bring up): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001361 stopServiceLocked(r);
1362 }
1363 }
1364
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001365 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001366 }
1367
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001368 private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07001369 for (int i=r.bindings.size()-1; i>=0; i--) {
1370 IntentBindRecord ibr = r.bindings.valueAt(i);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001371 if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001372 break;
1373 }
1374 }
1375 }
1376
1377 private final void realStartServiceLocked(ServiceRecord r,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001378 ProcessRecord app, boolean execInFg) throws RemoteException {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001379 if (app.thread == null) {
1380 throw new RemoteException();
1381 }
1382 if (DEBUG_MU)
1383 Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
1384 + ", ProcessRecord.uid = " + app.uid);
1385 r.app = app;
1386 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
1387
1388 app.services.add(r);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001389 bumpServiceExecutingLocked(r, execInFg, "create");
Dianne Hackborndb926082013-10-31 16:32:44 -07001390 mAm.updateLruProcessLocked(app, false, null);
1391 mAm.updateOomAdjLocked();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001392
1393 boolean created = false;
1394 try {
Dianne Hackborncf1171642013-07-12 17:26:02 -07001395 String nameTerm;
1396 int lastPeriod = r.shortName.lastIndexOf('.');
1397 nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
Jeff Sharkey9d6d8902012-11-09 17:32:43 -08001398 EventLogTags.writeAmCreateService(
Dianne Hackborncf1171642013-07-12 17:26:02 -07001399 r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001400 synchronized (r.stats.getBatteryStats()) {
1401 r.stats.startLaunchedLocked();
1402 }
1403 mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborna413dc02013-07-12 12:02:55 -07001404 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001405 app.thread.scheduleCreateService(r, r.serviceInfo,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001406 mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
1407 app.repProcState);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001408 r.postNotification();
1409 created = true;
1410 } finally {
1411 if (!created) {
1412 app.services.remove(r);
Dianne Hackbornbc72dce2013-11-11 10:43:38 -08001413 r.app = null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001414 scheduleServiceRestartLocked(r, false);
1415 }
1416 }
1417
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001418 requestServiceBindingsLocked(r, execInFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001419
1420 // If the service is in the started state, and there are no
1421 // pending arguments, then fake up one so its onStartCommand() will
1422 // be called.
1423 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
1424 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
1425 null, null));
1426 }
1427
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001428 sendServiceArgsLocked(r, execInFg, true);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001429
1430 if (r.delayed) {
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08001431 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "REM FR DELAY LIST (new proc): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001432 getServiceMap(r.userId).mDelayedStartList.remove(r);
1433 r.delayed = false;
1434 }
1435
1436 if (r.delayedStop) {
1437 // Oh and hey we've already been asked to stop!
1438 r.delayedStop = false;
1439 if (r.startRequested) {
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08001440 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Applying delayed stop (from start): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001441 stopServiceLocked(r);
1442 }
1443 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001444 }
1445
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001446 private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001447 boolean oomAdjusted) {
1448 final int N = r.pendingStarts.size();
1449 if (N == 0) {
1450 return;
1451 }
1452
1453 while (r.pendingStarts.size() > 0) {
1454 try {
1455 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
1456 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
1457 + r + " " + r.intent + " args=" + si.intent);
1458 if (si.intent == null && N > 1) {
1459 // If somehow we got a dummy null intent in the middle,
1460 // then skip it. DO NOT skip a null intent when it is
1461 // the only one in the list -- this is to support the
1462 // onStartCommand(null) case.
1463 continue;
1464 }
1465 si.deliveredTime = SystemClock.uptimeMillis();
1466 r.deliveredStarts.add(si);
1467 si.deliveryCount++;
1468 if (si.neededGrants != null) {
1469 mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
1470 si.getUriPermissionsLocked());
1471 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001472 bumpServiceExecutingLocked(r, execInFg, "start");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001473 if (!oomAdjusted) {
1474 oomAdjusted = true;
1475 mAm.updateOomAdjLocked(r.app);
1476 }
1477 int flags = 0;
1478 if (si.deliveryCount > 1) {
1479 flags |= Service.START_FLAG_RETRY;
1480 }
1481 if (si.doneExecutingCount > 0) {
1482 flags |= Service.START_FLAG_REDELIVERY;
1483 }
1484 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
1485 } catch (RemoteException e) {
1486 // Remote process gone... we'll let the normal cleanup take
1487 // care of this.
1488 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
1489 break;
1490 } catch (Exception e) {
1491 Slog.w(TAG, "Unexpected exception", e);
1492 break;
1493 }
1494 }
1495 }
1496
Dianne Hackborn164371f2013-10-01 19:10:13 -07001497 private final boolean isServiceNeeded(ServiceRecord r, boolean knowConn, boolean hasConn) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001498 // Are we still explicitly being asked to run?
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001499 if (r.startRequested) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001500 return true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001501 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001502
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001503 // Is someone still bound to us keepign us running?
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001504 if (!knowConn) {
1505 hasConn = r.hasAutoCreateConnections();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001506 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001507 if (hasConn) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001508 return true;
1509 }
1510
1511 return false;
1512 }
1513
1514 private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
1515 boolean hasConn) {
1516 //Slog.i(TAG, "Bring down service:");
1517 //r.dump(" ");
1518
1519 if (isServiceNeeded(r, knowConn, hasConn)) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001520 return;
1521 }
1522
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001523 // Are we in the process of launching?
1524 if (mPendingServices.contains(r)) {
1525 return;
1526 }
1527
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001528 bringDownServiceLocked(r);
1529 }
1530
1531 private final void bringDownServiceLocked(ServiceRecord r) {
1532 //Slog.i(TAG, "Bring down service:");
1533 //r.dump(" ");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001534
Dianne Hackborn390517b2013-05-30 15:03:32 -07001535 // Report to all of the connections that the service is no longer
1536 // available.
1537 for (int conni=r.connections.size()-1; conni>=0; conni--) {
1538 ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
1539 for (int i=0; i<c.size(); i++) {
1540 ConnectionRecord cr = c.get(i);
1541 // There is still a connection to the service that is
1542 // being brought down. Mark it as dead.
1543 cr.serviceDead = true;
1544 try {
1545 cr.conn.connected(r.name, null);
1546 } catch (Exception e) {
1547 Slog.w(TAG, "Failure disconnecting service " + r.name +
1548 " to connection " + c.get(i).conn.asBinder() +
1549 " (in " + c.get(i).binding.client.processName + ")", e);
1550 }
1551 }
1552 }
1553
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001554 // Tell the service that it has been unbound.
Dianne Hackborn390517b2013-05-30 15:03:32 -07001555 if (r.app != null && r.app.thread != null) {
1556 for (int i=r.bindings.size()-1; i>=0; i--) {
1557 IntentBindRecord ibr = r.bindings.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001558 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
1559 + ": hasBound=" + ibr.hasBound);
Dianne Hackborn390517b2013-05-30 15:03:32 -07001560 if (ibr.hasBound) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001561 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001562 bumpServiceExecutingLocked(r, false, "bring down unbind");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001563 mAm.updateOomAdjLocked(r.app);
1564 ibr.hasBound = false;
1565 r.app.thread.scheduleUnbindService(r,
1566 ibr.intent.getIntent());
1567 } catch (Exception e) {
1568 Slog.w(TAG, "Exception when unbinding service "
1569 + r.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001570 serviceProcessGoneLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001571 }
1572 }
1573 }
1574 }
1575
1576 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Jeff Sharkey9d6d8902012-11-09 17:32:43 -08001577 EventLogTags.writeAmDestroyService(
1578 r.userId, System.identityHashCode(r), (r.app != null) ? r.app.pid : -1);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001579
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001580 final ServiceMap smap = getServiceMap(r.userId);
1581 smap.mServicesByName.remove(r.name);
1582 smap.mServicesByIntent.remove(r.intent);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001583 r.totalRestartCount = 0;
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001584 unscheduleServiceRestartLocked(r, 0, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001585
1586 // Also make sure it is not on the pending list.
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001587 for (int i=mPendingServices.size()-1; i>=0; i--) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001588 if (mPendingServices.get(i) == r) {
1589 mPendingServices.remove(i);
1590 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001591 }
1592 }
1593
1594 r.cancelNotification();
1595 r.isForeground = false;
1596 r.foregroundId = 0;
1597 r.foregroundNoti = null;
1598
1599 // Clear start entries.
1600 r.clearDeliveredStartsLocked();
1601 r.pendingStarts.clear();
1602
1603 if (r.app != null) {
1604 synchronized (r.stats.getBatteryStats()) {
1605 r.stats.stopLaunchedLocked();
1606 }
1607 r.app.services.remove(r);
1608 if (r.app.thread != null) {
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001609 updateServiceForegroundLocked(r.app, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001610 try {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001611 bumpServiceExecutingLocked(r, false, "destroy");
1612 mDestroyingServices.add(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001613 mAm.updateOomAdjLocked(r.app);
1614 r.app.thread.scheduleStopService(r);
1615 } catch (Exception e) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001616 Slog.w(TAG, "Exception when destroying service "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001617 + r.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001618 serviceProcessGoneLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001619 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001620 } else {
1621 if (DEBUG_SERVICE) Slog.v(
1622 TAG, "Removed service that has no process: " + r);
1623 }
1624 } else {
1625 if (DEBUG_SERVICE) Slog.v(
1626 TAG, "Removed service that is not running: " + r);
1627 }
1628
1629 if (r.bindings.size() > 0) {
1630 r.bindings.clear();
1631 }
1632
1633 if (r.restarter instanceof ServiceRestarter) {
1634 ((ServiceRestarter)r.restarter).setService(null);
1635 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001636
Dianne Hackbornd2932242013-08-05 18:18:42 -07001637 int memFactor = mAm.mProcessStats.getMemFactorLocked();
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001638 long now = SystemClock.uptimeMillis();
1639 if (r.tracker != null) {
1640 r.tracker.setStarted(false, memFactor, now);
1641 r.tracker.setBound(false, memFactor, now);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001642 if (r.executeNesting == 0) {
Dianne Hackborn878deb32013-10-14 16:55:09 -07001643 r.tracker.clearCurrentOwner(r, false);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001644 r.tracker = null;
1645 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001646 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001647
1648 smap.ensureNotStartingBackground(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001649 }
1650
1651 void removeConnectionLocked(
1652 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
1653 IBinder binder = c.conn.asBinder();
1654 AppBindRecord b = c.binding;
1655 ServiceRecord s = b.service;
1656 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
1657 if (clist != null) {
1658 clist.remove(c);
1659 if (clist.size() == 0) {
1660 s.connections.remove(binder);
1661 }
1662 }
1663 b.connections.remove(c);
1664 if (c.activity != null && c.activity != skipAct) {
1665 if (c.activity.connections != null) {
1666 c.activity.connections.remove(c);
1667 }
1668 }
1669 if (b.client != skipApp) {
1670 b.client.connections.remove(c);
1671 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
1672 b.client.updateHasAboveClientLocked();
1673 }
Dianne Hackborndb926082013-10-31 16:32:44 -07001674 if (s.app != null) {
1675 updateServiceClientActivitiesLocked(s.app, c);
1676 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001677 }
1678 clist = mServiceConnections.get(binder);
1679 if (clist != null) {
1680 clist.remove(c);
1681 if (clist.size() == 0) {
1682 mServiceConnections.remove(binder);
1683 }
1684 }
1685
1686 if (b.connections.size() == 0) {
1687 b.intent.apps.remove(b.client);
1688 }
1689
1690 if (!c.serviceDead) {
1691 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
1692 + ": shouldUnbind=" + b.intent.hasBound);
1693 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
1694 && b.intent.hasBound) {
1695 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001696 bumpServiceExecutingLocked(s, false, "unbind");
Dianne Hackborndb926082013-10-31 16:32:44 -07001697 if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0
1698 && s.app.setProcState <= ActivityManager.PROCESS_STATE_RECEIVER) {
1699 // If this service's process is not already in the cached list,
1700 // then update it in the LRU list here because this may be causing
1701 // it to go down there and we want it to start out near the top.
1702 mAm.updateLruProcessLocked(s.app, false, null);
1703 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001704 mAm.updateOomAdjLocked(s.app);
1705 b.intent.hasBound = false;
1706 // Assume the client doesn't want to know about a rebind;
1707 // we will deal with that later if it asks for one.
1708 b.intent.doRebind = false;
1709 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
1710 } catch (Exception e) {
1711 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001712 serviceProcessGoneLocked(s);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001713 }
1714 }
1715
1716 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001717 boolean hasAutoCreate = s.hasAutoCreateConnections();
1718 if (!hasAutoCreate) {
1719 if (s.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001720 s.tracker.setBound(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001721 SystemClock.uptimeMillis());
1722 }
1723 }
1724 bringDownServiceIfNeededLocked(s, true, hasAutoCreate);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001725 }
1726 }
1727 }
1728
1729 void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001730 boolean inDestroying = mDestroyingServices.contains(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001731 if (r != null) {
1732 if (type == 1) {
1733 // This is a call from a service start... take care of
1734 // book-keeping.
1735 r.callStart = true;
1736 switch (res) {
1737 case Service.START_STICKY_COMPATIBILITY:
1738 case Service.START_STICKY: {
1739 // We are done with the associated start arguments.
1740 r.findDeliveredStart(startId, true);
1741 // Don't stop if killed.
1742 r.stopIfKilled = false;
1743 break;
1744 }
1745 case Service.START_NOT_STICKY: {
1746 // We are done with the associated start arguments.
1747 r.findDeliveredStart(startId, true);
1748 if (r.getLastStartId() == startId) {
1749 // There is no more work, and this service
1750 // doesn't want to hang around if killed.
1751 r.stopIfKilled = true;
1752 }
1753 break;
1754 }
1755 case Service.START_REDELIVER_INTENT: {
1756 // We'll keep this item until they explicitly
1757 // call stop for it, but keep track of the fact
1758 // that it was delivered.
1759 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
1760 if (si != null) {
1761 si.deliveryCount = 0;
1762 si.doneExecutingCount++;
1763 // Don't stop if killed.
1764 r.stopIfKilled = true;
1765 }
1766 break;
1767 }
1768 case Service.START_TASK_REMOVED_COMPLETE: {
1769 // Special processing for onTaskRemoved(). Don't
1770 // impact normal onStartCommand() processing.
1771 r.findDeliveredStart(startId, true);
1772 break;
1773 }
1774 default:
1775 throw new IllegalArgumentException(
1776 "Unknown service start result: " + res);
1777 }
1778 if (res == Service.START_STICKY_COMPATIBILITY) {
1779 r.callStart = false;
1780 }
1781 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001782 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn164371f2013-10-01 19:10:13 -07001783 serviceDoneExecutingLocked(r, inDestroying, inDestroying);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001784 Binder.restoreCallingIdentity(origId);
1785 } else {
1786 Slog.w(TAG, "Done executing unknown service from pid "
1787 + Binder.getCallingPid());
1788 }
1789 }
1790
Dianne Hackborn878deb32013-10-14 16:55:09 -07001791 private void serviceProcessGoneLocked(ServiceRecord r) {
1792 if (r.tracker != null) {
1793 int memFactor = mAm.mProcessStats.getMemFactorLocked();
1794 long now = SystemClock.uptimeMillis();
1795 r.tracker.setExecuting(false, memFactor, now);
1796 r.tracker.setBound(false, memFactor, now);
Dianne Hackbornbc72dce2013-11-11 10:43:38 -08001797 r.tracker.setStarted(false, memFactor, now);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001798 }
1799 serviceDoneExecutingLocked(r, true, true);
1800 }
1801
Dianne Hackborn164371f2013-10-01 19:10:13 -07001802 private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
1803 boolean finishing) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001804 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
1805 + ": nesting=" + r.executeNesting
Dianne Hackborn164371f2013-10-01 19:10:13 -07001806 + ", inDestroying=" + inDestroying + ", app=" + r.app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001807 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
1808 r.executeNesting--;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001809 if (r.executeNesting <= 0) {
1810 if (r.app != null) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001811 if (DEBUG_SERVICE) Slog.v(TAG,
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001812 "Nesting at 0 of " + r.shortName);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001813 r.app.execServicesFg = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001814 r.app.executingServices.remove(r);
1815 if (r.app.executingServices.size() == 0) {
1816 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
1817 "No more executingServices of " + r.shortName);
1818 mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001819 } else if (r.executeFg) {
1820 // Need to re-evaluate whether the app still needs to be in the foreground.
1821 for (int i=r.app.executingServices.size()-1; i>=0; i--) {
1822 if (r.app.executingServices.valueAt(i).executeFg) {
1823 r.app.execServicesFg = true;
1824 break;
1825 }
1826 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001827 }
Dianne Hackborn164371f2013-10-01 19:10:13 -07001828 if (inDestroying) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001829 if (DEBUG_SERVICE) Slog.v(TAG,
Dianne Hackborn164371f2013-10-01 19:10:13 -07001830 "doneExecuting remove destroying " + r);
1831 mDestroyingServices.remove(r);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001832 r.bindings.clear();
1833 }
1834 mAm.updateOomAdjLocked(r.app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001835 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001836 r.executeFg = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001837 if (r.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001838 r.tracker.setExecuting(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001839 SystemClock.uptimeMillis());
Dianne Hackborn164371f2013-10-01 19:10:13 -07001840 if (finishing) {
Dianne Hackborn878deb32013-10-14 16:55:09 -07001841 r.tracker.clearCurrentOwner(r, false);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001842 r.tracker = null;
1843 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001844 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001845 if (finishing) {
Dianne Hackborn90e9b1d2013-11-21 12:50:01 -08001846 if (r.app != null && !r.app.persistent) {
Dianne Hackbornddc19e92013-11-14 14:32:17 -08001847 r.app.services.remove(r);
1848 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001849 r.app = null;
1850 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001851 }
1852 }
1853
1854 boolean attachApplicationLocked(ProcessRecord proc, String processName) throws Exception {
1855 boolean didSomething = false;
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001856 // Collect any services that are waiting for this process to come up.
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001857 if (mPendingServices.size() > 0) {
1858 ServiceRecord sr = null;
1859 try {
1860 for (int i=0; i<mPendingServices.size(); i++) {
1861 sr = mPendingServices.get(i);
1862 if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
1863 || !processName.equals(sr.processName))) {
1864 continue;
1865 }
1866
1867 mPendingServices.remove(i);
1868 i--;
Dianne Hackbornd2932242013-08-05 18:18:42 -07001869 proc.addPackage(sr.appInfo.packageName, mAm.mProcessStats);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001870 realStartServiceLocked(sr, proc, sr.createdFromFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001871 didSomething = true;
1872 }
1873 } catch (Exception e) {
1874 Slog.w(TAG, "Exception in new application when starting service "
1875 + sr.shortName, e);
1876 throw e;
1877 }
1878 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001879 // Also, if there are any services that are waiting to restart and
1880 // would run in this process, now is a good time to start them. It would
1881 // be weird to bring up the process but arbitrarily not let the services
1882 // run at this point just because their restart time hasn't come up.
1883 if (mRestartingServices.size() > 0) {
1884 ServiceRecord sr = null;
1885 for (int i=0; i<mRestartingServices.size(); i++) {
1886 sr = mRestartingServices.get(i);
1887 if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
1888 || !processName.equals(sr.processName))) {
1889 continue;
1890 }
1891 mAm.mHandler.removeCallbacks(sr.restarter);
1892 mAm.mHandler.post(sr.restarter);
1893 }
1894 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001895 return didSomething;
1896 }
1897
1898 void processStartTimedOutLocked(ProcessRecord proc) {
1899 for (int i=0; i<mPendingServices.size(); i++) {
1900 ServiceRecord sr = mPendingServices.get(i);
1901 if ((proc.uid == sr.appInfo.uid
1902 && proc.processName.equals(sr.processName))
1903 || sr.isolatedProc == proc) {
1904 Slog.w(TAG, "Forcing bringing down service: " + sr);
1905 sr.isolatedProc = null;
1906 mPendingServices.remove(i);
1907 i--;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001908 bringDownServiceLocked(sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001909 }
1910 }
1911 }
1912
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001913 private boolean collectForceStopServicesLocked(String name, int userId,
1914 boolean evenPersistent, boolean doit,
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001915 ArrayMap<ComponentName, ServiceRecord> services,
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001916 ArrayList<ServiceRecord> result) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001917 boolean didSomething = false;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001918 for (int i=0; i<services.size(); i++) {
1919 ServiceRecord service = services.valueAt(i);
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001920 if ((name == null || service.packageName.equals(name))
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001921 && (service.app == null || evenPersistent || !service.app.persistent)) {
1922 if (!doit) {
1923 return true;
1924 }
1925 didSomething = true;
1926 Slog.i(TAG, " Force stopping service " + service);
1927 if (service.app != null) {
1928 service.app.removed = true;
Dianne Hackborn90e9b1d2013-11-21 12:50:01 -08001929 if (!service.app.persistent) {
1930 service.app.services.remove(service);
1931 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001932 }
1933 service.app = null;
1934 service.isolatedProc = null;
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001935 result.add(service);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001936 }
1937 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001938 return didSomething;
1939 }
1940
1941 boolean forceStopLocked(String name, int userId, boolean evenPersistent, boolean doit) {
1942 boolean didSomething = false;
1943 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
1944 if (userId == UserHandle.USER_ALL) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001945 for (int i=0; i<mServiceMap.size(); i++) {
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001946 didSomething |= collectForceStopServicesLocked(name, userId, evenPersistent,
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001947 doit, mServiceMap.valueAt(i).mServicesByName, services);
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001948 if (!doit && didSomething) {
1949 return true;
1950 }
1951 }
1952 } else {
Amith Yamasani540b6592013-10-01 13:02:52 -07001953 ServiceMap smap = mServiceMap.get(userId);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001954 if (smap != null) {
1955 ArrayMap<ComponentName, ServiceRecord> items = smap.mServicesByName;
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07001956 didSomething = collectForceStopServicesLocked(name, userId, evenPersistent,
1957 doit, items, services);
1958 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001959 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001960
1961 int N = services.size();
1962 for (int i=0; i<N; i++) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001963 bringDownServiceLocked(services.get(i));
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001964 }
1965 return didSomething;
1966 }
1967
1968 void cleanUpRemovedTaskLocked(TaskRecord tr, ComponentName component, Intent baseIntent) {
1969 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001970 ArrayMap<ComponentName, ServiceRecord> alls = getServices(tr.userId);
1971 for (int i=0; i<alls.size(); i++) {
1972 ServiceRecord sr = alls.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001973 if (sr.packageName.equals(component.getPackageName())) {
1974 services.add(sr);
1975 }
1976 }
1977
1978 // Take care of any running services associated with the app.
1979 for (int i=0; i<services.size(); i++) {
1980 ServiceRecord sr = services.get(i);
1981 if (sr.startRequested) {
1982 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
1983 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
1984 stopServiceLocked(sr);
1985 } else {
1986 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
1987 sr.makeNextStartId(), baseIntent, null));
1988 if (sr.app != null && sr.app.thread != null) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001989 // We always run in the foreground, since this is called as
1990 // part of the "remove task" UI operation.
1991 sendServiceArgsLocked(sr, true, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001992 }
1993 }
1994 }
1995 }
1996 }
1997
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001998 final void killServicesLocked(ProcessRecord app, boolean allowRestart) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001999 // Report disconnected services.
2000 if (false) {
2001 // XXX we are letting the client link to the service for
2002 // death notifications.
2003 if (app.services.size() > 0) {
2004 Iterator<ServiceRecord> it = app.services.iterator();
2005 while (it.hasNext()) {
2006 ServiceRecord r = it.next();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002007 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2008 ArrayList<ConnectionRecord> cl = r.connections.valueAt(conni);
2009 for (int i=0; i<cl.size(); i++) {
2010 ConnectionRecord c = cl.get(i);
2011 if (c.binding.client != app) {
2012 try {
2013 //c.conn.connected(r.className, null);
2014 } catch (Exception e) {
2015 // todo: this should be asynchronous!
2016 Slog.w(TAG, "Exception thrown disconnected servce "
2017 + r.shortName
2018 + " from app " + app.processName, e);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002019 }
2020 }
2021 }
2022 }
2023 }
2024 }
2025 }
2026
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002027 // First clear app state from services.
Dianne Hackbornc8230512013-07-13 21:32:12 -07002028 for (int i=app.services.size()-1; i>=0; i--) {
Dianne Hackbornc8230512013-07-13 21:32:12 -07002029 ServiceRecord sr = app.services.valueAt(i);
2030 synchronized (sr.stats.getBatteryStats()) {
2031 sr.stats.stopLaunchedLocked();
2032 }
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08002033 if (sr.app != app && sr.app != null && !sr.app.persistent) {
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002034 sr.app.services.remove(sr);
2035 }
Dianne Hackbornc8230512013-07-13 21:32:12 -07002036 sr.app = null;
2037 sr.isolatedProc = null;
2038 sr.executeNesting = 0;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002039 sr.forceClearTracker();
2040 if (mDestroyingServices.remove(sr)) {
2041 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove destroying " + sr);
Dianne Hackbornc8230512013-07-13 21:32:12 -07002042 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002043
Dianne Hackbornc8230512013-07-13 21:32:12 -07002044 final int numClients = sr.bindings.size();
2045 for (int bindingi=numClients-1; bindingi>=0; bindingi--) {
2046 IntentBindRecord b = sr.bindings.valueAt(bindingi);
2047 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
2048 + ": shouldUnbind=" + b.hasBound);
2049 b.binder = null;
2050 b.requested = b.received = b.hasBound = false;
2051 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002052 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002053
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002054 // Clean up any connections this application has to other services.
2055 for (int i=app.connections.size()-1; i>=0; i--) {
2056 ConnectionRecord r = app.connections.valueAt(i);
2057 removeConnectionLocked(r, app, null);
2058 }
2059 app.connections.clear();
2060
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002061 ServiceMap smap = getServiceMap(app.userId);
2062
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002063 // Now do remaining service cleanup.
2064 for (int i=app.services.size()-1; i>=0; i--) {
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002065 ServiceRecord sr = app.services.valueAt(i);
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08002066
2067 // Unless the process is persistent, this process record is going away,
2068 // so make sure the service is cleaned out of it.
2069 if (!app.persistent) {
Dianne Hackborn4190fc52013-12-09 18:20:16 -08002070 app.services.removeAt(i);
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08002071 }
2072
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002073 // Sanity check: if the service listed for the app is not one
Dianne Hackborn4190fc52013-12-09 18:20:16 -08002074 // we actually are maintaining, just let it drop.
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002075 if (smap.mServicesByName.get(sr.name) != sr) {
2076 ServiceRecord cur = smap.mServicesByName.get(sr.name);
2077 Slog.wtf(TAG, "Service " + sr + " in process " + app
2078 + " not same as in map: " + cur);
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002079 continue;
2080 }
2081
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002082 // Any services running in the application may need to be placed
2083 // back in the pending list.
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002084 if (allowRestart && sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
Dianne Hackbornc8230512013-07-13 21:32:12 -07002085 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
2086 Slog.w(TAG, "Service crashed " + sr.crashCount
2087 + " times, stopping: " + sr);
2088 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
2089 sr.userId, sr.crashCount, sr.shortName, app.pid);
2090 bringDownServiceLocked(sr);
2091 } else if (!allowRestart) {
2092 bringDownServiceLocked(sr);
2093 } else {
2094 boolean canceled = scheduleServiceRestartLocked(sr, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002095
Dianne Hackbornc8230512013-07-13 21:32:12 -07002096 // Should the service remain running? Note that in the
2097 // extreme case of so many attempts to deliver a command
2098 // that it failed we also will stop it here.
2099 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
2100 if (sr.pendingStarts.size() == 0) {
2101 sr.startRequested = false;
2102 if (sr.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07002103 sr.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackbornc8230512013-07-13 21:32:12 -07002104 SystemClock.uptimeMillis());
2105 }
2106 if (!sr.hasAutoCreateConnections()) {
2107 // Whoops, no reason to restart!
2108 bringDownServiceLocked(sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002109 }
2110 }
2111 }
2112 }
Dianne Hackbornc8230512013-07-13 21:32:12 -07002113 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002114
Dianne Hackbornc8230512013-07-13 21:32:12 -07002115 if (!allowRestart) {
2116 app.services.clear();
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002117
2118 // Make sure there are no more restarting services for this process.
2119 for (int i=mRestartingServices.size()-1; i>=0; i--) {
2120 ServiceRecord r = mRestartingServices.get(i);
2121 if (r.processName.equals(app.processName) &&
2122 r.serviceInfo.applicationInfo.uid == app.info.uid) {
2123 mRestartingServices.remove(i);
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08002124 clearRestartingIfNeededLocked(r);
2125 }
2126 }
2127 for (int i=mPendingServices.size()-1; i>=0; i--) {
2128 ServiceRecord r = mPendingServices.get(i);
2129 if (r.processName.equals(app.processName) &&
2130 r.serviceInfo.applicationInfo.uid == app.info.uid) {
2131 mPendingServices.remove(i);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002132 }
2133 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002134 }
2135
2136 // Make sure we have no more records on the stopping list.
Dianne Hackborn164371f2013-10-01 19:10:13 -07002137 int i = mDestroyingServices.size();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002138 while (i > 0) {
2139 i--;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002140 ServiceRecord sr = mDestroyingServices.get(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002141 if (sr.app == app) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07002142 sr.forceClearTracker();
2143 mDestroyingServices.remove(i);
2144 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove destroying " + sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002145 }
2146 }
2147
2148 app.executingServices.clear();
2149 }
2150
2151 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
2152 ActivityManager.RunningServiceInfo info =
2153 new ActivityManager.RunningServiceInfo();
2154 info.service = r.name;
2155 if (r.app != null) {
2156 info.pid = r.app.pid;
2157 }
2158 info.uid = r.appInfo.uid;
2159 info.process = r.processName;
2160 info.foreground = r.isForeground;
2161 info.activeSince = r.createTime;
2162 info.started = r.startRequested;
2163 info.clientCount = r.connections.size();
2164 info.crashCount = r.crashCount;
2165 info.lastActivityTime = r.lastActivity;
2166 if (r.isForeground) {
2167 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
2168 }
2169 if (r.startRequested) {
2170 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
2171 }
2172 if (r.app != null && r.app.pid == ActivityManagerService.MY_PID) {
2173 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
2174 }
2175 if (r.app != null && r.app.persistent) {
2176 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
2177 }
2178
Dianne Hackborn390517b2013-05-30 15:03:32 -07002179 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2180 ArrayList<ConnectionRecord> connl = r.connections.valueAt(conni);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002181 for (int i=0; i<connl.size(); i++) {
2182 ConnectionRecord conn = connl.get(i);
2183 if (conn.clientLabel != 0) {
2184 info.clientPackage = conn.binding.client.info.packageName;
2185 info.clientLabel = conn.clientLabel;
2186 return info;
2187 }
2188 }
2189 }
2190 return info;
2191 }
2192
2193 List<ActivityManager.RunningServiceInfo> getRunningServiceInfoLocked(int maxNum,
2194 int flags) {
2195 ArrayList<ActivityManager.RunningServiceInfo> res
2196 = new ArrayList<ActivityManager.RunningServiceInfo>();
2197
Dianne Hackborn0c380492012-08-20 17:23:30 -07002198 final int uid = Binder.getCallingUid();
2199 final long ident = Binder.clearCallingIdentity();
2200 try {
2201 if (ActivityManager.checkUidPermission(
2202 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2203 uid) == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn1676c852012-09-10 14:52:30 -07002204 int[] users = mAm.getUsersLocked();
2205 for (int ui=0; ui<users.length && res.size() < maxNum; ui++) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002206 ArrayMap<ComponentName, ServiceRecord> alls = getServices(users[ui]);
2207 for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
2208 ServiceRecord sr = alls.valueAt(i);
2209 res.add(makeRunningServiceInfoLocked(sr));
Dianne Hackborn0c380492012-08-20 17:23:30 -07002210 }
2211 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002212
Dianne Hackborn0c380492012-08-20 17:23:30 -07002213 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
2214 ServiceRecord r = mRestartingServices.get(i);
2215 ActivityManager.RunningServiceInfo info =
2216 makeRunningServiceInfoLocked(r);
2217 info.restarting = r.nextRestartTime;
2218 res.add(info);
2219 }
2220 } else {
2221 int userId = UserHandle.getUserId(uid);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002222 ArrayMap<ComponentName, ServiceRecord> alls = getServices(userId);
2223 for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
2224 ServiceRecord sr = alls.valueAt(i);
2225 res.add(makeRunningServiceInfoLocked(sr));
Dianne Hackborn0c380492012-08-20 17:23:30 -07002226 }
2227
2228 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
2229 ServiceRecord r = mRestartingServices.get(i);
2230 if (r.userId == userId) {
2231 ActivityManager.RunningServiceInfo info =
2232 makeRunningServiceInfoLocked(r);
2233 info.restarting = r.nextRestartTime;
2234 res.add(info);
2235 }
2236 }
2237 }
2238 } finally {
2239 Binder.restoreCallingIdentity(ident);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002240 }
2241
2242 return res;
2243 }
2244
2245 public PendingIntent getRunningServiceControlPanelLocked(ComponentName name) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07002246 int userId = UserHandle.getUserId(Binder.getCallingUid());
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002247 ServiceRecord r = getServiceByName(name, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002248 if (r != null) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002249 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2250 ArrayList<ConnectionRecord> conn = r.connections.valueAt(conni);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002251 for (int i=0; i<conn.size(); i++) {
2252 if (conn.get(i).clientIntent != null) {
2253 return conn.get(i).clientIntent;
2254 }
2255 }
2256 }
2257 }
2258 return null;
2259 }
2260
2261 void serviceTimeout(ProcessRecord proc) {
2262 String anrMessage = null;
2263
2264 synchronized(this) {
2265 if (proc.executingServices.size() == 0 || proc.thread == null) {
2266 return;
2267 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002268 long maxTime = SystemClock.uptimeMillis() -
2269 (proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002270 ServiceRecord timeout = null;
2271 long nextTime = 0;
Dianne Hackbornc8230512013-07-13 21:32:12 -07002272 for (int i=proc.executingServices.size()-1; i>=0; i--) {
2273 ServiceRecord sr = proc.executingServices.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002274 if (sr.executingStart < maxTime) {
2275 timeout = sr;
2276 break;
2277 }
2278 if (sr.executingStart > nextTime) {
2279 nextTime = sr.executingStart;
2280 }
2281 }
2282 if (timeout != null && mAm.mLruProcesses.contains(proc)) {
2283 Slog.w(TAG, "Timeout executing service: " + timeout);
2284 anrMessage = "Executing service " + timeout.shortName;
2285 } else {
2286 Message msg = mAm.mHandler.obtainMessage(
2287 ActivityManagerService.SERVICE_TIMEOUT_MSG);
2288 msg.obj = proc;
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002289 mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg
Dianne Hackborn2be00932013-09-22 16:46:00 -07002290 ? (nextTime+SERVICE_TIMEOUT) : (nextTime + SERVICE_BACKGROUND_TIMEOUT));
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002291 }
2292 }
2293
2294 if (anrMessage != null) {
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -07002295 mAm.appNotResponding(proc, null, null, false, anrMessage);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002296 }
2297 }
2298
Dianne Hackborn2be00932013-09-22 16:46:00 -07002299 void scheduleServiceTimeoutLocked(ProcessRecord proc) {
2300 if (proc.executingServices.size() == 0 || proc.thread == null) {
2301 return;
2302 }
2303 long now = SystemClock.uptimeMillis();
2304 Message msg = mAm.mHandler.obtainMessage(
2305 ActivityManagerService.SERVICE_TIMEOUT_MSG);
2306 msg.obj = proc;
2307 mAm.mHandler.sendMessageAtTime(msg,
2308 proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
2309 }
2310
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002311 /**
2312 * Prints a list of ServiceRecords (dumpsys activity services)
2313 */
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002314 void dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002315 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
2316 boolean needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002317 boolean printedAnything = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002318
2319 ItemMatcher matcher = new ItemMatcher();
2320 matcher.build(args, opti);
2321
2322 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
2323 try {
Dianne Hackborn1676c852012-09-10 14:52:30 -07002324 int[] users = mAm.getUsersLocked();
2325 for (int user : users) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002326 ServiceMap smap = getServiceMap(user);
2327 boolean printed = false;
2328 if (smap.mServicesByName.size() > 0) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002329 long nowReal = SystemClock.elapsedRealtime();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002330 needSep = false;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002331 for (int si=0; si<smap.mServicesByName.size(); si++) {
2332 ServiceRecord r = smap.mServicesByName.valueAt(si);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002333 if (!matcher.match(r, r.name)) {
2334 continue;
2335 }
2336 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2337 continue;
2338 }
2339 if (!printed) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002340 if (printedAnything) {
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07002341 pw.println();
2342 }
Dianne Hackborn1676c852012-09-10 14:52:30 -07002343 pw.println(" User " + user + " active services:");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002344 printed = true;
2345 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002346 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002347 if (needSep) {
2348 pw.println();
2349 }
2350 pw.print(" * ");
2351 pw.println(r);
2352 if (dumpAll) {
2353 r.dump(pw, " ");
2354 needSep = true;
2355 } else {
2356 pw.print(" app=");
2357 pw.println(r.app);
2358 pw.print(" created=");
2359 TimeUtils.formatDuration(r.createTime, nowReal, pw);
2360 pw.print(" started=");
2361 pw.print(r.startRequested);
2362 pw.print(" connections=");
2363 pw.println(r.connections.size());
2364 if (r.connections.size() > 0) {
2365 pw.println(" Connections:");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002366 for (int conni=0; conni<r.connections.size(); conni++) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002367 ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002368 for (int i = 0; i < clist.size(); i++) {
2369 ConnectionRecord conn = clist.get(i);
2370 pw.print(" ");
2371 pw.print(conn.binding.intent.intent.getIntent()
2372 .toShortString(false, false, false, false));
2373 pw.print(" -> ");
2374 ProcessRecord proc = conn.binding.client;
2375 pw.println(proc != null ? proc.toShortString() : "null");
2376 }
2377 }
2378 }
2379 }
2380 if (dumpClient && r.app != null && r.app.thread != null) {
2381 pw.println(" Client:");
2382 pw.flush();
2383 try {
2384 TransferPipe tp = new TransferPipe();
2385 try {
2386 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(),
2387 r, args);
2388 tp.setBufferPrefix(" ");
2389 // Short timeout, since blocking here can
2390 // deadlock with the application.
2391 tp.go(fd, 2000);
2392 } finally {
2393 tp.kill();
2394 }
2395 } catch (IOException e) {
2396 pw.println(" Failure while dumping the service: " + e);
2397 } catch (RemoteException e) {
2398 pw.println(" Got a RemoteException while dumping the service");
2399 }
2400 needSep = true;
2401 }
2402 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002403 needSep |= printed;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002404 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002405 printed = false;
2406 for (int si=0, SN=smap.mDelayedStartList.size(); si<SN; si++) {
2407 ServiceRecord r = smap.mDelayedStartList.get(si);
2408 if (!matcher.match(r, r.name)) {
2409 continue;
2410 }
2411 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2412 continue;
2413 }
2414 if (!printed) {
2415 if (printedAnything) {
2416 pw.println();
2417 }
2418 pw.println(" User " + user + " delayed start services:");
2419 printed = true;
2420 }
2421 printedAnything = true;
2422 pw.print(" * Delayed start "); pw.println(r);
2423 }
2424 printed = false;
2425 for (int si=0, SN=smap.mStartingBackground.size(); si<SN; si++) {
2426 ServiceRecord r = smap.mStartingBackground.get(si);
2427 if (!matcher.match(r, r.name)) {
2428 continue;
2429 }
2430 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2431 continue;
2432 }
2433 if (!printed) {
2434 if (printedAnything) {
2435 pw.println();
2436 }
2437 pw.println(" User " + user + " starting in background:");
2438 printed = true;
2439 }
2440 printedAnything = true;
2441 pw.print(" * Starting bg "); pw.println(r);
2442 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002443 }
Amith Yamasani258848d2012-08-10 17:06:33 -07002444 } catch (Exception e) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002445 Slog.w(TAG, "Exception in dumpServicesLocked", e);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002446 }
2447
2448 if (mPendingServices.size() > 0) {
2449 boolean printed = false;
2450 for (int i=0; i<mPendingServices.size(); i++) {
2451 ServiceRecord r = mPendingServices.get(i);
2452 if (!matcher.match(r, r.name)) {
2453 continue;
2454 }
2455 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2456 continue;
2457 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002458 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002459 if (!printed) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002460 if (needSep) pw.println();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002461 needSep = true;
2462 pw.println(" Pending services:");
2463 printed = true;
2464 }
2465 pw.print(" * Pending "); pw.println(r);
2466 r.dump(pw, " ");
2467 }
2468 needSep = true;
2469 }
2470
2471 if (mRestartingServices.size() > 0) {
2472 boolean printed = false;
2473 for (int i=0; i<mRestartingServices.size(); i++) {
2474 ServiceRecord r = mRestartingServices.get(i);
2475 if (!matcher.match(r, r.name)) {
2476 continue;
2477 }
2478 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2479 continue;
2480 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002481 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002482 if (!printed) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002483 if (needSep) pw.println();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002484 needSep = true;
2485 pw.println(" Restarting services:");
2486 printed = true;
2487 }
2488 pw.print(" * Restarting "); pw.println(r);
2489 r.dump(pw, " ");
2490 }
2491 needSep = true;
2492 }
2493
Dianne Hackborn164371f2013-10-01 19:10:13 -07002494 if (mDestroyingServices.size() > 0) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002495 boolean printed = false;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002496 for (int i=0; i< mDestroyingServices.size(); i++) {
2497 ServiceRecord r = mDestroyingServices.get(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002498 if (!matcher.match(r, r.name)) {
2499 continue;
2500 }
2501 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2502 continue;
2503 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002504 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002505 if (!printed) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002506 if (needSep) pw.println();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002507 needSep = true;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002508 pw.println(" Destroying services:");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002509 printed = true;
2510 }
Dianne Hackborn164371f2013-10-01 19:10:13 -07002511 pw.print(" * Destroy "); pw.println(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002512 r.dump(pw, " ");
2513 }
2514 needSep = true;
2515 }
2516
2517 if (dumpAll) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002518 boolean printed = false;
2519 for (int ic=0; ic<mServiceConnections.size(); ic++) {
2520 ArrayList<ConnectionRecord> r = mServiceConnections.valueAt(ic);
2521 for (int i=0; i<r.size(); i++) {
2522 ConnectionRecord cr = r.get(i);
2523 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
2524 continue;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002525 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002526 if (dumpPackage != null && (cr.binding.client == null
2527 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
2528 continue;
2529 }
2530 printedAnything = true;
2531 if (!printed) {
2532 if (needSep) pw.println();
2533 needSep = true;
2534 pw.println(" Connection bindings to services:");
2535 printed = true;
2536 }
2537 pw.print(" * "); pw.println(cr);
2538 cr.dump(pw, " ");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002539 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002540 }
2541 }
2542
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002543 if (!printedAnything) {
2544 pw.println(" (nothing)");
2545 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002546 }
2547
2548 /**
2549 * There are three ways to call this:
2550 * - no service specified: dump all the services
2551 * - a flattened component name that matched an existing service was specified as the
2552 * first arg: dump that one service
2553 * - the first arg isn't the flattened component name of an existing service:
2554 * dump all services whose component contains the first arg as a substring
2555 */
2556 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
2557 int opti, boolean dumpAll) {
2558 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
2559
Dianne Hackborn1676c852012-09-10 14:52:30 -07002560 synchronized (this) {
2561 int[] users = mAm.getUsersLocked();
2562 if ("all".equals(name)) {
2563 for (int user : users) {
Dianne Hackborn13c590d2013-10-07 14:32:00 -07002564 ServiceMap smap = mServiceMap.get(user);
2565 if (smap == null) {
2566 continue;
2567 }
2568 ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002569 for (int i=0; i<alls.size(); i++) {
2570 ServiceRecord r1 = alls.valueAt(i);
Amith Yamasani258848d2012-08-10 17:06:33 -07002571 services.add(r1);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002572 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002573 }
Dianne Hackborn1676c852012-09-10 14:52:30 -07002574 } else {
2575 ComponentName componentName = name != null
2576 ? ComponentName.unflattenFromString(name) : null;
2577 int objectId = 0;
2578 if (componentName == null) {
2579 // Not a '/' separated full component name; maybe an object ID?
2580 try {
2581 objectId = Integer.parseInt(name, 16);
2582 name = null;
2583 componentName = null;
2584 } catch (RuntimeException e) {
2585 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002586 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002587
Dianne Hackborn1676c852012-09-10 14:52:30 -07002588 for (int user : users) {
Dianne Hackborn13c590d2013-10-07 14:32:00 -07002589 ServiceMap smap = mServiceMap.get(user);
2590 if (smap == null) {
2591 continue;
2592 }
2593 ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002594 for (int i=0; i<alls.size(); i++) {
2595 ServiceRecord r1 = alls.valueAt(i);
Amith Yamasani258848d2012-08-10 17:06:33 -07002596 if (componentName != null) {
2597 if (r1.name.equals(componentName)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002598 services.add(r1);
2599 }
Amith Yamasani258848d2012-08-10 17:06:33 -07002600 } else if (name != null) {
2601 if (r1.name.flattenToString().contains(name)) {
2602 services.add(r1);
2603 }
2604 } else if (System.identityHashCode(r1) == objectId) {
2605 services.add(r1);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002606 }
2607 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002608 }
2609 }
2610 }
2611
2612 if (services.size() <= 0) {
2613 return false;
2614 }
2615
2616 boolean needSep = false;
2617 for (int i=0; i<services.size(); i++) {
2618 if (needSep) {
2619 pw.println();
2620 }
2621 needSep = true;
2622 dumpService("", fd, pw, services.get(i), args, dumpAll);
2623 }
2624 return true;
2625 }
2626
2627 /**
2628 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
2629 * there is a thread associated with the service.
2630 */
2631 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
2632 final ServiceRecord r, String[] args, boolean dumpAll) {
2633 String innerPrefix = prefix + " ";
2634 synchronized (this) {
2635 pw.print(prefix); pw.print("SERVICE ");
2636 pw.print(r.shortName); pw.print(" ");
2637 pw.print(Integer.toHexString(System.identityHashCode(r)));
2638 pw.print(" pid=");
2639 if (r.app != null) pw.println(r.app.pid);
2640 else pw.println("(not running)");
2641 if (dumpAll) {
2642 r.dump(pw, innerPrefix);
2643 }
2644 }
2645 if (r.app != null && r.app.thread != null) {
2646 pw.print(prefix); pw.println(" Client:");
2647 pw.flush();
2648 try {
2649 TransferPipe tp = new TransferPipe();
2650 try {
2651 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
2652 tp.setBufferPrefix(prefix + " ");
2653 tp.go(fd);
2654 } finally {
2655 tp.kill();
2656 }
2657 } catch (IOException e) {
2658 pw.println(prefix + " Failure while dumping the service: " + e);
2659 } catch (RemoteException e) {
2660 pw.println(prefix + " Got a RemoteException while dumping the service");
2661 }
2662 }
2663 }
2664
2665}