blob: 108a079bcb72c6ef0172beed0381428af60fdbc3 [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--;
Junu Kimfcb87362014-02-19 16:25:21 +0900207 i--;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700208 }
209 }
210 while (mDelayedStartList.size() > 0
211 && mStartingBackground.size() < mMaxStartingBackground) {
212 ServiceRecord r = mDelayedStartList.remove(0);
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800213 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "REM FR DELAY LIST (exec next): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700214 if (r.pendingStarts.size() <= 0) {
215 Slog.w(TAG, "**** NO PENDING STARTS! " + r + " startReq=" + r.startRequested
216 + " delayedStop=" + r.delayedStop);
217 }
218 if (DEBUG_DELAYED_SERVICE) {
219 if (mDelayedStartList.size() > 0) {
220 Slog.v(TAG, "Remaining delayed list:");
221 for (int i=0; i<mDelayedStartList.size(); i++) {
222 Slog.v(TAG, " #" + i + ": " + mDelayedStartList.get(i));
223 }
224 }
225 }
226 r.delayed = false;
227 startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false, true);
228 }
229 if (mStartingBackground.size() > 0) {
230 ServiceRecord next = mStartingBackground.get(0);
231 long when = next.startingBgTimeout > now ? next.startingBgTimeout : now;
232 if (DEBUG_DELAYED_SERVICE) Slog.v(TAG, "Top bg start is " + next
233 + ", can delay others up to " + when);
234 Message msg = obtainMessage(MSG_BG_START_TIMEOUT);
235 sendMessageAtTime(msg, when);
236 }
Dianne Hackborn6285a322013-09-18 12:09:47 -0700237 if (mStartingBackground.size() < mMaxStartingBackground) {
238 mAm.backgroundServicesFinishedLocked(mUserId);
239 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700240 }
241 }
242
243 public ActiveServices(ActivityManagerService service) {
244 mAm = service;
Dianne Hackborn23037412013-11-04 18:11:29 -0800245 int maxBg = 0;
246 try {
247 maxBg = Integer.parseInt(SystemProperties.get("ro.config.max_starting_bg", "0"));
248 } catch(RuntimeException e) {
249 }
Dianne Hackborn20d94742014-05-29 18:35:45 -0700250 mMaxStartingBackground = maxBg > 0
251 ? maxBg : ActivityManager.isLowRamDeviceStatic() ? 1 : 8;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700252 }
253
254 ServiceRecord getServiceByName(ComponentName name, int callingUser) {
255 // TODO: Deal with global services
256 if (DEBUG_MU)
257 Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
258 return getServiceMap(callingUser).mServicesByName.get(name);
259 }
260
Dianne Hackborn6285a322013-09-18 12:09:47 -0700261 boolean hasBackgroundServices(int callingUser) {
262 ServiceMap smap = mServiceMap.get(callingUser);
263 return smap != null ? smap.mStartingBackground.size() >= mMaxStartingBackground : false;
264 }
265
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700266 private ServiceMap getServiceMap(int callingUser) {
267 ServiceMap smap = mServiceMap.get(callingUser);
268 if (smap == null) {
Dianne Hackborn13c590d2013-10-07 14:32:00 -0700269 smap = new ServiceMap(mAm.mHandler.getLooper(), callingUser);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700270 mServiceMap.put(callingUser, smap);
271 }
272 return smap;
273 }
274
275 ArrayMap<ComponentName, ServiceRecord> getServices(int callingUser) {
276 return getServiceMap(callingUser).mServicesByName;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700277 }
278
279 ComponentName startServiceLocked(IApplicationThread caller,
280 Intent service, String resolvedType,
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700281 int callingPid, int callingUid, int userId) {
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800282 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "startService: " + service
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700283 + " type=" + resolvedType + " args=" + service.getExtras());
284
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700285 final boolean callerFg;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700286 if (caller != null) {
287 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
288 if (callerApp == null) {
289 throw new SecurityException(
290 "Unable to find app for caller " + caller
291 + " (pid=" + Binder.getCallingPid()
292 + ") when starting service " + service);
293 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700294 callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
295 } else {
296 callerFg = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700297 }
298
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700299
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700300 ServiceLookupResult res =
301 retrieveServiceLocked(service, resolvedType,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700302 callingPid, callingUid, userId, true, callerFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700303 if (res == null) {
304 return null;
305 }
306 if (res.record == null) {
307 return new ComponentName("!", res.permission != null
308 ? res.permission : "private to package");
309 }
310 ServiceRecord r = res.record;
311 NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
312 callingUid, r.packageName, service, service.getFlags(), null);
Dianne Hackbornd6f5b622013-11-11 17:25:37 -0800313 if (unscheduleServiceRestartLocked(r, callingUid, false)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700314 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
315 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700316 r.lastActivity = SystemClock.uptimeMillis();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700317 r.startRequested = true;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700318 r.delayedStop = false;
319 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
320 service, neededGrants));
321
322 final ServiceMap smap = getServiceMap(r.userId);
323 boolean addToStarting = false;
324 if (!callerFg && r.app == null && mAm.mStartedUsers.get(r.userId) != null) {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700325 ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700326 if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700327 // If this is not coming from a foreground caller, then we may want
328 // to delay the start if there are already other background services
329 // that are starting. This is to avoid process start spam when lots
330 // of applications are all handling things like connectivity broadcasts.
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700331 // We only do this for cached processes, because otherwise an application
332 // can have assumptions about calling startService() for a service to run
333 // in its own process, and for that process to not be killed before the
334 // service is started. This is especially the case for receivers, which
335 // may start a service in onReceive() to do some additional work and have
336 // initialized some global state as part of that.
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700337 if (DEBUG_DELAYED_SERVICE) Slog.v(TAG, "Potential start delay of " + r + " in "
338 + proc);
339 if (r.delayed) {
340 // This service is already scheduled for a delayed start; just leave
341 // it still waiting.
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800342 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Continuing to delay: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700343 return r.name;
344 }
345 if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
346 // Something else is starting, delay!
347 Slog.i(TAG, "Delaying start of: " + r);
348 smap.mDelayedStartList.add(r);
349 r.delayed = true;
350 return r.name;
351 }
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800352 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Not delaying: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700353 addToStarting = true;
354 } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
355 // We slightly loosen when we will enqueue this new service as a background
356 // starting service we are waiting for, to also include processes that are
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700357 // currently running other services or receivers.
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700358 addToStarting = true;
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800359 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Not delaying, but counting as bg: " + r);
360 } else if (DEBUG_DELAYED_STARTS) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700361 StringBuilder sb = new StringBuilder(128);
362 sb.append("Not potential delay (state=").append(proc.curProcState)
363 .append(' ').append(proc.adjType);
364 String reason = proc.makeAdjReason();
365 if (reason != null) {
366 sb.append(' ');
367 sb.append(reason);
368 }
369 sb.append("): ");
370 sb.append(r.toString());
371 Slog.v(TAG, sb.toString());
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700372 }
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800373 } else if (DEBUG_DELAYED_STARTS) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700374 if (callerFg) {
375 Slog.v(TAG, "Not potential delay (callerFg=" + callerFg + " uid="
376 + callingUid + " pid=" + callingPid + "): " + r);
377 } else if (r.app != null) {
378 Slog.v(TAG, "Not potential delay (cur app=" + r.app + "): " + r);
379 } else {
380 Slog.v(TAG, "Not potential delay (user " + r.userId + " not started): " + r);
381 }
382 }
383
384 return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
385 }
386
387 ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
388 ServiceRecord r, boolean callerFg, boolean addToStarting) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700389 ProcessStats.ServiceState stracker = r.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -0700390 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700391 stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700392 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700393 r.callStart = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700394 synchronized (r.stats.getBatteryStats()) {
395 r.stats.startRunningLocked();
396 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700397 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -0700398 if (error != null) {
399 return new ComponentName("!!", error);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700400 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700401
402 if (r.startRequested && addToStarting) {
403 boolean first = smap.mStartingBackground.size() == 0;
404 smap.mStartingBackground.add(r);
405 r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
406 if (DEBUG_DELAYED_SERVICE) {
407 RuntimeException here = new RuntimeException("here");
408 here.fillInStackTrace();
409 Slog.v(TAG, "Starting background (first=" + first + "): " + r, here);
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800410 } else if (DEBUG_DELAYED_STARTS) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700411 Slog.v(TAG, "Starting background (first=" + first + "): " + r);
412 }
413 if (first) {
414 smap.rescheduleDelayedStarts();
415 }
416 } else if (callerFg) {
417 smap.ensureNotStartingBackground(r);
418 }
419
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700420 return r.name;
421 }
422
423 private void stopServiceLocked(ServiceRecord service) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700424 if (service.delayed) {
425 // If service isn't actually running, but is is being held in the
426 // delayed list, then we need to keep it started but note that it
427 // should be stopped once no longer delayed.
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800428 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Delaying stop of pending: " + service);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700429 service.delayedStop = true;
430 return;
431 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700432 synchronized (service.stats.getBatteryStats()) {
433 service.stats.stopRunningLocked();
434 }
435 service.startRequested = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700436 if (service.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700437 service.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700438 SystemClock.uptimeMillis());
439 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700440 service.callStart = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700441 bringDownServiceIfNeededLocked(service, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700442 }
443
444 int stopServiceLocked(IApplicationThread caller, Intent service,
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700445 String resolvedType, int userId) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700446 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
447 + " type=" + resolvedType);
448
449 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
450 if (caller != null && callerApp == null) {
451 throw new SecurityException(
452 "Unable to find app for caller " + caller
453 + " (pid=" + Binder.getCallingPid()
454 + ") when stopping service " + service);
455 }
456
457 // If this service is active, make sure it is stopped.
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -0700458 ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700459 Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700460 if (r != null) {
461 if (r.record != null) {
462 final long origId = Binder.clearCallingIdentity();
463 try {
464 stopServiceLocked(r.record);
465 } finally {
466 Binder.restoreCallingIdentity(origId);
467 }
468 return 1;
469 }
470 return -1;
471 }
472
473 return 0;
474 }
475
476 IBinder peekServiceLocked(Intent service, String resolvedType) {
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -0700477 ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
478 Binder.getCallingPid(), Binder.getCallingUid(),
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700479 UserHandle.getCallingUserId(), false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700480
481 IBinder ret = null;
482 if (r != null) {
483 // r.record is null if findServiceLocked() failed the caller permission check
484 if (r.record == null) {
485 throw new SecurityException(
486 "Permission Denial: Accessing service " + r.record.name
487 + " from pid=" + Binder.getCallingPid()
488 + ", uid=" + Binder.getCallingUid()
489 + " requires " + r.permission);
490 }
491 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
492 if (ib != null) {
493 ret = ib.binder;
494 }
495 }
496
497 return ret;
498 }
499
500 boolean stopServiceTokenLocked(ComponentName className, IBinder token,
501 int startId) {
502 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
503 + " " + token + " startId=" + startId);
Dianne Hackborn41203752012-08-31 14:05:51 -0700504 ServiceRecord r = findServiceLocked(className, token, UserHandle.getCallingUserId());
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700505 if (r != null) {
506 if (startId >= 0) {
507 // Asked to only stop if done with all work. Note that
508 // to avoid leaks, we will take this as dropping all
509 // start items up to and including this one.
510 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
511 if (si != null) {
512 while (r.deliveredStarts.size() > 0) {
513 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
514 cur.removeUriPermissionsLocked();
515 if (cur == si) {
516 break;
517 }
518 }
519 }
520
521 if (r.getLastStartId() != startId) {
522 return false;
523 }
524
525 if (r.deliveredStarts.size() > 0) {
526 Slog.w(TAG, "stopServiceToken startId " + startId
527 + " is last, but have " + r.deliveredStarts.size()
528 + " remaining args");
529 }
530 }
531
532 synchronized (r.stats.getBatteryStats()) {
533 r.stats.stopRunningLocked();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700534 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700535 r.startRequested = false;
536 if (r.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700537 r.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700538 SystemClock.uptimeMillis());
539 }
540 r.callStart = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700541 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700542 bringDownServiceIfNeededLocked(r, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700543 Binder.restoreCallingIdentity(origId);
544 return true;
545 }
546 return false;
547 }
548
549 public void setServiceForegroundLocked(ComponentName className, IBinder token,
550 int id, Notification notification, boolean removeNotification) {
Dianne Hackborn41203752012-08-31 14:05:51 -0700551 final int userId = UserHandle.getCallingUserId();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700552 final long origId = Binder.clearCallingIdentity();
553 try {
Dianne Hackborn41203752012-08-31 14:05:51 -0700554 ServiceRecord r = findServiceLocked(className, token, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700555 if (r != null) {
556 if (id != 0) {
557 if (notification == null) {
558 throw new IllegalArgumentException("null notification");
559 }
560 if (r.foregroundId != id) {
561 r.cancelNotification();
562 r.foregroundId = id;
563 }
564 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
565 r.foregroundNoti = notification;
566 r.isForeground = true;
567 r.postNotification();
568 if (r.app != null) {
569 updateServiceForegroundLocked(r.app, true);
570 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700571 getServiceMap(r.userId).ensureNotStartingBackground(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700572 } else {
573 if (r.isForeground) {
574 r.isForeground = false;
575 if (r.app != null) {
Dianne Hackborndb926082013-10-31 16:32:44 -0700576 mAm.updateLruProcessLocked(r.app, false, null);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700577 updateServiceForegroundLocked(r.app, true);
578 }
579 }
580 if (removeNotification) {
581 r.cancelNotification();
582 r.foregroundId = 0;
583 r.foregroundNoti = null;
584 }
585 }
586 }
587 } finally {
588 Binder.restoreCallingIdentity(origId);
589 }
590 }
591
592 private void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
593 boolean anyForeground = false;
Dianne Hackbornc8230512013-07-13 21:32:12 -0700594 for (int i=proc.services.size()-1; i>=0; i--) {
595 ServiceRecord sr = proc.services.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700596 if (sr.isForeground) {
597 anyForeground = true;
598 break;
599 }
600 }
Dianne Hackborneaf2ac42014-02-07 13:01:07 -0800601 mAm.updateProcessForegroundLocked(proc, anyForeground, oomAdj);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700602 }
603
Dianne Hackborndb926082013-10-31 16:32:44 -0700604 private boolean updateServiceClientActivitiesLocked(ProcessRecord proc,
605 ConnectionRecord modCr) {
606 if (modCr != null && modCr.binding.client != null) {
607 if (modCr.binding.client.activities.size() <= 0) {
608 // This connection is from a client without activities, so adding
609 // and removing is not interesting.
610 return false;
611 }
612 }
613
614 boolean anyClientActivities = false;
615 for (int i=proc.services.size()-1; i>=0 && !anyClientActivities; i--) {
616 ServiceRecord sr = proc.services.valueAt(i);
617 for (int conni=sr.connections.size()-1; conni>=0 && !anyClientActivities; conni--) {
618 ArrayList<ConnectionRecord> clist = sr.connections.valueAt(conni);
619 for (int cri=clist.size()-1; cri>=0; cri--) {
620 ConnectionRecord cr = clist.get(cri);
621 if (cr.binding.client == null || cr.binding.client == proc) {
622 // Binding to ourself is not interesting.
623 continue;
624 }
625 if (cr.binding.client.activities.size() > 0) {
626 anyClientActivities = true;
627 break;
628 }
629 }
630 }
631 }
632 if (anyClientActivities != proc.hasClientActivities) {
633 proc.hasClientActivities = anyClientActivities;
634 mAm.updateLruProcessLocked(proc, anyClientActivities, null);
635 return true;
636 }
637 return false;
638 }
639
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700640 int bindServiceLocked(IApplicationThread caller, IBinder token,
641 Intent service, String resolvedType,
642 IServiceConnection connection, int flags, int userId) {
643 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
644 + " type=" + resolvedType + " conn=" + connection.asBinder()
645 + " flags=0x" + Integer.toHexString(flags));
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700646 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
647 if (callerApp == null) {
648 throw new SecurityException(
649 "Unable to find app for caller " + caller
650 + " (pid=" + Binder.getCallingPid()
651 + ") when binding service " + service);
652 }
653
654 ActivityRecord activity = null;
655 if (token != null) {
Craig Mautnerd2328952013-03-05 12:46:26 -0800656 activity = ActivityRecord.isInStackLocked(token);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700657 if (activity == null) {
658 Slog.w(TAG, "Binding with unknown activity: " + token);
659 return 0;
660 }
661 }
662
663 int clientLabel = 0;
664 PendingIntent clientIntent = null;
665
666 if (callerApp.info.uid == Process.SYSTEM_UID) {
667 // Hacky kind of thing -- allow system stuff to tell us
668 // what they are, so we can report this elsewhere for
669 // others to know why certain services are running.
670 try {
Dianne Hackbornf0f94d12014-03-17 16:04:21 -0700671 clientIntent = service.getParcelableExtra(Intent.EXTRA_CLIENT_INTENT);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700672 } catch (RuntimeException e) {
673 }
674 if (clientIntent != null) {
675 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
676 if (clientLabel != 0) {
677 // There are no useful extras in the intent, trash them.
678 // System code calling with this stuff just needs to know
679 // this will happen.
680 service = service.cloneFilter();
681 }
682 }
683 }
684
Dianne Hackbornf0f94d12014-03-17 16:04:21 -0700685 if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
686 mAm.enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
687 "BIND_TREAT_LIKE_ACTIVITY");
688 }
689
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700690 final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
691
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700692 ServiceLookupResult res =
693 retrieveServiceLocked(service, resolvedType,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700694 Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700695 if (res == null) {
696 return 0;
697 }
698 if (res.record == null) {
699 return -1;
700 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700701 ServiceRecord s = res.record;
702
703 final long origId = Binder.clearCallingIdentity();
704
705 try {
Dianne Hackbornd6f5b622013-11-11 17:25:37 -0800706 if (unscheduleServiceRestartLocked(s, callerApp.info.uid, false)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700707 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
708 + s);
709 }
710
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700711 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
712 s.lastActivity = SystemClock.uptimeMillis();
713 if (!s.hasAutoCreateConnections()) {
714 // This is the first binding, let the tracker know.
Dianne Hackbornd2932242013-08-05 18:18:42 -0700715 ProcessStats.ServiceState stracker = s.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -0700716 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700717 stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700718 s.lastActivity);
719 }
720 }
721 }
722
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700723 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
724 ConnectionRecord c = new ConnectionRecord(b, activity,
725 connection, flags, clientLabel, clientIntent);
726
727 IBinder binder = connection.asBinder();
728 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
729 if (clist == null) {
730 clist = new ArrayList<ConnectionRecord>();
731 s.connections.put(binder, clist);
732 }
733 clist.add(c);
734 b.connections.add(c);
735 if (activity != null) {
736 if (activity.connections == null) {
737 activity.connections = new HashSet<ConnectionRecord>();
738 }
739 activity.connections.add(c);
740 }
741 b.client.connections.add(c);
742 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
743 b.client.hasAboveClient = true;
744 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700745 if (s.app != null) {
746 updateServiceClientActivitiesLocked(s.app, c);
747 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700748 clist = mServiceConnections.get(binder);
749 if (clist == null) {
750 clist = new ArrayList<ConnectionRecord>();
751 mServiceConnections.put(binder, clist);
752 }
753 clist.add(c);
754
755 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
756 s.lastActivity = SystemClock.uptimeMillis();
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700757 if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700758 return 0;
759 }
760 }
761
762 if (s.app != null) {
Dianne Hackbornf0f94d12014-03-17 16:04:21 -0700763 if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
764 s.app.treatLikeActivity = true;
765 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700766 // This could have made the service more important.
Dianne Hackbornf0f94d12014-03-17 16:04:21 -0700767 mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities
768 || s.app.treatLikeActivity, b.client);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700769 mAm.updateOomAdjLocked(s.app);
770 }
771
772 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
773 + ": received=" + b.intent.received
774 + " apps=" + b.intent.apps.size()
775 + " doRebind=" + b.intent.doRebind);
776
777 if (s.app != null && b.intent.received) {
778 // Service is already running, so we can immediately
779 // publish the connection.
780 try {
781 c.conn.connected(s.name, b.intent.binder);
782 } catch (Exception e) {
783 Slog.w(TAG, "Failure sending service " + s.shortName
784 + " to connection " + c.conn.asBinder()
785 + " (in " + c.binding.client.processName + ")", e);
786 }
787
788 // If this is the first app connected back to this binding,
789 // and the service had previously asked to be told when
790 // rebound, then do so.
791 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700792 requestServiceBindingLocked(s, b.intent, callerFg, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700793 }
794 } else if (!b.intent.requested) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700795 requestServiceBindingLocked(s, b.intent, callerFg, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700796 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700797
798 getServiceMap(s.userId).ensureNotStartingBackground(s);
799
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700800 } finally {
801 Binder.restoreCallingIdentity(origId);
802 }
803
804 return 1;
805 }
806
807 void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
808 final long origId = Binder.clearCallingIdentity();
809 try {
810 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
811 + " " + intent + ": " + service);
812 if (r != null) {
813 Intent.FilterComparison filter
814 = new Intent.FilterComparison(intent);
815 IntentBindRecord b = r.bindings.get(filter);
816 if (b != null && !b.received) {
817 b.binder = service;
818 b.requested = true;
819 b.received = true;
Dianne Hackborn390517b2013-05-30 15:03:32 -0700820 for (int conni=r.connections.size()-1; conni>=0; conni--) {
821 ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
822 for (int i=0; i<clist.size(); i++) {
823 ConnectionRecord c = clist.get(i);
824 if (!filter.equals(c.binding.intent.intent)) {
825 if (DEBUG_SERVICE) Slog.v(
826 TAG, "Not publishing to: " + c);
827 if (DEBUG_SERVICE) Slog.v(
828 TAG, "Bound intent: " + c.binding.intent.intent);
829 if (DEBUG_SERVICE) Slog.v(
830 TAG, "Published intent: " + intent);
831 continue;
832 }
833 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
834 try {
835 c.conn.connected(r.name, service);
836 } catch (Exception e) {
837 Slog.w(TAG, "Failure sending service " + r.name +
838 " to connection " + c.conn.asBinder() +
839 " (in " + c.binding.client.processName + ")", e);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700840 }
841 }
842 }
843 }
844
Dianne Hackborn164371f2013-10-01 19:10:13 -0700845 serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700846 }
847 } finally {
848 Binder.restoreCallingIdentity(origId);
849 }
850 }
851
852 boolean unbindServiceLocked(IServiceConnection connection) {
853 IBinder binder = connection.asBinder();
854 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
855 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
856 if (clist == null) {
857 Slog.w(TAG, "Unbind failed: could not find connection for "
858 + connection.asBinder());
859 return false;
860 }
861
862 final long origId = Binder.clearCallingIdentity();
863 try {
864 while (clist.size() > 0) {
865 ConnectionRecord r = clist.get(0);
866 removeConnectionLocked(r, null, null);
867
868 if (r.binding.service.app != null) {
869 // This could have made the service less important.
Dianne Hackbornf0f94d12014-03-17 16:04:21 -0700870 if ((r.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
871 r.binding.service.app.treatLikeActivity = true;
872 mAm.updateLruProcessLocked(r.binding.service.app,
873 r.binding.service.app.hasClientActivities
874 || r.binding.service.app.treatLikeActivity, null);
875 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700876 mAm.updateOomAdjLocked(r.binding.service.app);
877 }
878 }
879 } finally {
880 Binder.restoreCallingIdentity(origId);
881 }
882
883 return true;
884 }
885
886 void unbindFinishedLocked(ServiceRecord r, Intent intent, boolean doRebind) {
887 final long origId = Binder.clearCallingIdentity();
888 try {
889 if (r != null) {
890 Intent.FilterComparison filter
891 = new Intent.FilterComparison(intent);
892 IntentBindRecord b = r.bindings.get(filter);
893 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
894 + " at " + b + ": apps="
895 + (b != null ? b.apps.size() : 0));
896
Dianne Hackborn164371f2013-10-01 19:10:13 -0700897 boolean inDestroying = mDestroyingServices.contains(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700898 if (b != null) {
Dianne Hackborn164371f2013-10-01 19:10:13 -0700899 if (b.apps.size() > 0 && !inDestroying) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700900 // Applications have already bound since the last
901 // unbind, so just rebind right here.
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700902 boolean inFg = false;
903 for (int i=b.apps.size()-1; i>=0; i--) {
904 ProcessRecord client = b.apps.valueAt(i).client;
905 if (client != null && client.setSchedGroup
906 != Process.THREAD_GROUP_BG_NONINTERACTIVE) {
907 inFg = true;
908 break;
909 }
910 }
911 requestServiceBindingLocked(r, b, inFg, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700912 } else {
913 // Note to tell the service the next time there is
914 // a new client.
915 b.doRebind = true;
916 }
917 }
918
Dianne Hackborn164371f2013-10-01 19:10:13 -0700919 serviceDoneExecutingLocked(r, inDestroying, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700920 }
921 } finally {
922 Binder.restoreCallingIdentity(origId);
923 }
924 }
925
926 private final ServiceRecord findServiceLocked(ComponentName name,
Dianne Hackborn41203752012-08-31 14:05:51 -0700927 IBinder token, int userId) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700928 ServiceRecord r = getServiceByName(name, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700929 return r == token ? r : null;
930 }
931
932 private final class ServiceLookupResult {
933 final ServiceRecord record;
934 final String permission;
935
936 ServiceLookupResult(ServiceRecord _record, String _permission) {
937 record = _record;
938 permission = _permission;
939 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700940 }
941
942 private class ServiceRestarter implements Runnable {
943 private ServiceRecord mService;
944
945 void setService(ServiceRecord service) {
946 mService = service;
947 }
948
949 public void run() {
950 synchronized(mAm) {
951 performServiceRestartLocked(mService);
952 }
953 }
954 }
955
956 private ServiceLookupResult retrieveServiceLocked(Intent service,
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -0700957 String resolvedType, int callingPid, int callingUid, int userId,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700958 boolean createIfNeeded, boolean callingFromFg) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700959 ServiceRecord r = null;
960 if (DEBUG_SERVICE) Slog.v(TAG, "retrieveServiceLocked: " + service
961 + " type=" + resolvedType + " callingUid=" + callingUid);
962
Dianne Hackborn139748f2012-09-24 11:36:57 -0700963 userId = mAm.handleIncomingUser(callingPid, callingUid, userId,
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700964 false, true, "service", null);
965
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700966 ServiceMap smap = getServiceMap(userId);
967 final ComponentName comp = service.getComponent();
968 if (comp != null) {
969 r = smap.mServicesByName.get(comp);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700970 }
971 if (r == null) {
972 Intent.FilterComparison filter = new Intent.FilterComparison(service);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700973 r = smap.mServicesByIntent.get(filter);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700974 }
975 if (r == null) {
976 try {
977 ResolveInfo rInfo =
978 AppGlobals.getPackageManager().resolveService(
979 service, resolvedType,
980 ActivityManagerService.STOCK_PM_FLAGS, userId);
981 ServiceInfo sInfo =
982 rInfo != null ? rInfo.serviceInfo : null;
983 if (sInfo == null) {
Amith Yamasani2b914652012-08-27 12:04:40 -0700984 Slog.w(TAG, "Unable to start service " + service + " U=" + userId +
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700985 ": not found");
986 return null;
987 }
988 ComponentName name = new ComponentName(
989 sInfo.applicationInfo.packageName, sInfo.name);
990 if (userId > 0) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700991 if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
992 sInfo.name, sInfo.flags)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700993 userId = 0;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700994 smap = getServiceMap(0);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700995 }
996 sInfo = new ServiceInfo(sInfo);
997 sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
998 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700999 r = smap.mServicesByName.get(name);
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001000 if (r == null && createIfNeeded) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001001 Intent.FilterComparison filter
1002 = new Intent.FilterComparison(service.cloneFilter());
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001003 ServiceRestarter res = new ServiceRestarter();
1004 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
1005 BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics();
1006 synchronized (stats) {
1007 ss = stats.getServiceStatsLocked(
1008 sInfo.applicationInfo.uid, sInfo.packageName,
1009 sInfo.name);
1010 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001011 r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001012 res.setService(r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001013 smap.mServicesByName.put(name, r);
1014 smap.mServicesByIntent.put(filter, r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001015
1016 // Make sure this component isn't in the pending list.
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001017 for (int i=mPendingServices.size()-1; i>=0; i--) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001018 ServiceRecord pr = mPendingServices.get(i);
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001019 if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
1020 && pr.name.equals(name)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001021 mPendingServices.remove(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001022 }
1023 }
1024 }
1025 } catch (RemoteException ex) {
1026 // pm is in same process, this will never happen.
1027 }
1028 }
1029 if (r != null) {
1030 if (mAm.checkComponentPermission(r.permission,
1031 callingPid, callingUid, r.appInfo.uid, r.exported)
1032 != PackageManager.PERMISSION_GRANTED) {
1033 if (!r.exported) {
1034 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
1035 + " from pid=" + callingPid
1036 + ", uid=" + callingUid
1037 + " that is not exported from uid " + r.appInfo.uid);
1038 return new ServiceLookupResult(null, "not exported from uid "
1039 + r.appInfo.uid);
1040 }
1041 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
1042 + " from pid=" + callingPid
1043 + ", uid=" + callingUid
1044 + " requires " + r.permission);
1045 return new ServiceLookupResult(null, r.permission);
1046 }
Ben Gruverf5323fe2013-07-31 15:09:51 -07001047 if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
1048 resolvedType, r.appInfo)) {
Ben Gruverb6223792013-07-29 16:35:40 -07001049 return null;
1050 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001051 return new ServiceLookupResult(r, null);
1052 }
1053 return null;
1054 }
1055
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001056 private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001057 if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001058 + why + " of " + r + " in app " + r.app);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001059 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, ">>> EXECUTING "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001060 + why + " of " + r.shortName);
1061 long now = SystemClock.uptimeMillis();
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001062 if (r.executeNesting == 0) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001063 r.executeFg = fg;
Dianne Hackbornd2932242013-08-05 18:18:42 -07001064 ProcessStats.ServiceState stracker = r.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001065 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001066 stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001067 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001068 if (r.app != null) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001069 r.app.executingServices.add(r);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001070 r.app.execServicesFg |= fg;
Dianne Hackborn2be00932013-09-22 16:46:00 -07001071 if (r.app.executingServices.size() == 1) {
1072 scheduleServiceTimeoutLocked(r.app);
1073 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001074 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001075 } else if (r.app != null && fg && !r.app.execServicesFg) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001076 r.app.execServicesFg = true;
Dianne Hackborn2be00932013-09-22 16:46:00 -07001077 scheduleServiceTimeoutLocked(r.app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001078 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001079 r.executeFg |= fg;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001080 r.executeNesting++;
1081 r.executingStart = now;
1082 }
1083
1084 private final boolean requestServiceBindingLocked(ServiceRecord r,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001085 IntentBindRecord i, boolean execInFg, boolean rebind) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001086 if (r.app == null || r.app.thread == null) {
1087 // If service is not currently running, can't yet bind.
1088 return false;
1089 }
1090 if ((!i.requested || rebind) && i.apps.size() > 0) {
1091 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001092 bumpServiceExecutingLocked(r, execInFg, "bind");
Dianne Hackborna413dc02013-07-12 12:02:55 -07001093 r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
1094 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
1095 r.app.repProcState);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001096 if (!rebind) {
1097 i.requested = true;
1098 }
1099 i.hasBound = true;
1100 i.doRebind = false;
1101 } catch (RemoteException e) {
1102 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
1103 return false;
1104 }
1105 }
1106 return true;
1107 }
1108
1109 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
1110 boolean allowCancel) {
1111 boolean canceled = false;
1112
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001113 ServiceMap smap = getServiceMap(r.userId);
1114 if (smap.mServicesByName.get(r.name) != r) {
1115 ServiceRecord cur = smap.mServicesByName.get(r.name);
1116 Slog.wtf(TAG, "Attempting to schedule restart of " + r
1117 + " when found in map: " + cur);
1118 return false;
1119 }
1120
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001121 final long now = SystemClock.uptimeMillis();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001122
1123 if ((r.serviceInfo.applicationInfo.flags
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001124 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
1125 long minDuration = SERVICE_RESTART_DURATION;
1126 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001127
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001128 // Any delivered but not yet finished starts should be put back
1129 // on the pending list.
1130 final int N = r.deliveredStarts.size();
1131 if (N > 0) {
1132 for (int i=N-1; i>=0; i--) {
1133 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
1134 si.removeUriPermissionsLocked();
1135 if (si.intent == null) {
1136 // We'll generate this again if needed.
1137 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
1138 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
1139 r.pendingStarts.add(0, si);
1140 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
1141 dur *= 2;
1142 if (minDuration < dur) minDuration = dur;
1143 if (resetTime < dur) resetTime = dur;
1144 } else {
1145 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
1146 + r.name);
1147 canceled = true;
1148 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001149 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001150 r.deliveredStarts.clear();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001151 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001152
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001153 r.totalRestartCount++;
1154 if (r.restartDelay == 0) {
1155 r.restartCount++;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001156 r.restartDelay = minDuration;
1157 } else {
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001158 // If it has been a "reasonably long time" since the service
1159 // was started, then reset our restart duration back to
1160 // the beginning, so we don't infinitely increase the duration
1161 // on a service that just occasionally gets killed (which is
1162 // a normal case, due to process being killed to reclaim memory).
1163 if (now > (r.restartTime+resetTime)) {
1164 r.restartCount = 1;
1165 r.restartDelay = minDuration;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001166 } else {
Dianne Hackborn7b492722013-11-01 09:58:45 -07001167 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
1168 if (r.restartDelay < minDuration) {
1169 r.restartDelay = minDuration;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001170 }
1171 }
1172 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001173
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001174 r.nextRestartTime = now + r.restartDelay;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001175
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001176 // Make sure that we don't end up restarting a bunch of services
1177 // all at the same time.
1178 boolean repeat;
1179 do {
1180 repeat = false;
1181 for (int i=mRestartingServices.size()-1; i>=0; i--) {
1182 ServiceRecord r2 = mRestartingServices.get(i);
1183 if (r2 != r && r.nextRestartTime
1184 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
1185 && r.nextRestartTime
1186 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
1187 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
1188 r.restartDelay = r.nextRestartTime - now;
1189 repeat = true;
1190 break;
1191 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001192 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001193 } while (repeat);
1194
1195 } else {
Dianne Hackborn7b492722013-11-01 09:58:45 -07001196 // Persistent processes are immediately restarted, so there is no
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001197 // reason to hold of on restarting their services.
1198 r.totalRestartCount++;
1199 r.restartCount = 0;
1200 r.restartDelay = 0;
1201 r.nextRestartTime = now;
1202 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001203
1204 if (!mRestartingServices.contains(r)) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001205 r.createdFromFg = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001206 mRestartingServices.add(r);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001207 r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001208 }
1209
1210 r.cancelNotification();
1211
1212 mAm.mHandler.removeCallbacks(r.restarter);
1213 mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime);
1214 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
1215 Slog.w(TAG, "Scheduling restart of crashed service "
1216 + r.shortName + " in " + r.restartDelay + "ms");
1217 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001218 r.userId, r.shortName, r.restartDelay);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001219
1220 return canceled;
1221 }
1222
1223 final void performServiceRestartLocked(ServiceRecord r) {
1224 if (!mRestartingServices.contains(r)) {
1225 return;
1226 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001227 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001228 }
1229
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001230 private final boolean unscheduleServiceRestartLocked(ServiceRecord r, int callingUid,
1231 boolean force) {
1232 if (!force && r.restartDelay == 0) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001233 return false;
1234 }
Dianne Hackborn7b492722013-11-01 09:58:45 -07001235 // Remove from the restarting list; if the service is currently on the
1236 // restarting list, or the call is coming from another app, then this
1237 // service has become of much more interest so we reset the restart interval.
1238 boolean removed = mRestartingServices.remove(r);
1239 if (removed || callingUid != r.appInfo.uid) {
1240 r.resetRestartCounter();
1241 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001242 if (removed) {
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001243 clearRestartingIfNeededLocked(r);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001244 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001245 mAm.mHandler.removeCallbacks(r.restarter);
1246 return true;
1247 }
1248
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001249 private void clearRestartingIfNeededLocked(ServiceRecord r) {
1250 if (r.restartTracker != null) {
1251 // If this is the last restarting record with this tracker, then clear
1252 // the tracker's restarting state.
1253 boolean stillTracking = false;
1254 for (int i=mRestartingServices.size()-1; i>=0; i--) {
1255 if (mRestartingServices.get(i).restartTracker == r.restartTracker) {
1256 stillTracking = true;
1257 break;
1258 }
1259 }
1260 if (!stillTracking) {
1261 r.restartTracker.setRestarting(false, mAm.mProcessStats.getMemFactorLocked(),
1262 SystemClock.uptimeMillis());
1263 r.restartTracker = null;
1264 }
1265 }
1266 }
1267
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001268 private final String bringUpServiceLocked(ServiceRecord r,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001269 int intentFlags, boolean execInFg, boolean whileRestarting) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001270 //Slog.i(TAG, "Bring up service:");
1271 //r.dump(" ");
1272
1273 if (r.app != null && r.app.thread != null) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001274 sendServiceArgsLocked(r, execInFg, false);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001275 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001276 }
1277
1278 if (!whileRestarting && r.restartDelay > 0) {
1279 // If waiting for a restart, then do nothing.
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001280 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001281 }
1282
1283 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
1284
1285 // We are now bringing the service up, so no longer in the
1286 // restarting state.
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001287 if (mRestartingServices.remove(r)) {
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001288 clearRestartingIfNeededLocked(r);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001289 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001290
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001291 // Make sure this service is no longer considered delayed, we are starting it now.
1292 if (r.delayed) {
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08001293 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "REM FR DELAY LIST (bring up): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001294 getServiceMap(r.userId).mDelayedStartList.remove(r);
1295 r.delayed = false;
1296 }
1297
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001298 // Make sure that the user who owns this service is started. If not,
1299 // we don't want to allow it to run.
1300 if (mAm.mStartedUsers.get(r.userId) == null) {
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001301 String msg = "Unable to launch app "
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001302 + r.appInfo.packageName + "/"
1303 + r.appInfo.uid + " for service "
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001304 + r.intent.getIntent() + ": user " + r.userId + " is stopped";
1305 Slog.w(TAG, msg);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001306 bringDownServiceLocked(r);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001307 return msg;
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001308 }
1309
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001310 // Service is now being launched, its package can't be stopped.
1311 try {
1312 AppGlobals.getPackageManager().setPackageStoppedState(
1313 r.packageName, false, r.userId);
1314 } catch (RemoteException e) {
1315 } catch (IllegalArgumentException e) {
1316 Slog.w(TAG, "Failed trying to unstop package "
1317 + r.packageName + ": " + e);
1318 }
1319
1320 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
1321 final String procName = r.processName;
1322 ProcessRecord app;
1323
1324 if (!isolated) {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001325 app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
1326 if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
1327 + " app=" + app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001328 if (app != null && app.thread != null) {
1329 try {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001330 app.addPackage(r.appInfo.packageName, mAm.mProcessStats);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001331 realStartServiceLocked(r, app, execInFg);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001332 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001333 } catch (RemoteException e) {
1334 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
1335 }
1336
1337 // If a dead object exception was thrown -- fall through to
1338 // restart the application.
1339 }
1340 } else {
1341 // If this service runs in an isolated process, then each time
1342 // we call startProcessLocked() we will get a new isolated
1343 // process, starting another process if we are currently waiting
1344 // for a previous process to come up. To deal with this, we store
1345 // in the service any current isolated process it is running in or
1346 // waiting to have come up.
1347 app = r.isolatedProc;
1348 }
1349
1350 // Not running -- get it started, and enqueue this service record
1351 // to be executed when the app comes up.
1352 if (app == null) {
1353 if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001354 "service", r.name, false, isolated, false)) == null) {
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001355 String msg = "Unable to launch app "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001356 + r.appInfo.packageName + "/"
1357 + r.appInfo.uid + " for service "
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001358 + r.intent.getIntent() + ": process is bad";
1359 Slog.w(TAG, msg);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001360 bringDownServiceLocked(r);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001361 return msg;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001362 }
1363 if (isolated) {
1364 r.isolatedProc = app;
1365 }
1366 }
1367
1368 if (!mPendingServices.contains(r)) {
1369 mPendingServices.add(r);
1370 }
1371
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001372 if (r.delayedStop) {
1373 // Oh and hey we've already been asked to stop!
1374 r.delayedStop = false;
1375 if (r.startRequested) {
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08001376 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Applying delayed stop (in bring up): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001377 stopServiceLocked(r);
1378 }
1379 }
1380
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001381 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001382 }
1383
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001384 private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07001385 for (int i=r.bindings.size()-1; i>=0; i--) {
1386 IntentBindRecord ibr = r.bindings.valueAt(i);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001387 if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001388 break;
1389 }
1390 }
1391 }
1392
1393 private final void realStartServiceLocked(ServiceRecord r,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001394 ProcessRecord app, boolean execInFg) throws RemoteException {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001395 if (app.thread == null) {
1396 throw new RemoteException();
1397 }
1398 if (DEBUG_MU)
1399 Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
1400 + ", ProcessRecord.uid = " + app.uid);
1401 r.app = app;
1402 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
1403
1404 app.services.add(r);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001405 bumpServiceExecutingLocked(r, execInFg, "create");
Dianne Hackborndb926082013-10-31 16:32:44 -07001406 mAm.updateLruProcessLocked(app, false, null);
1407 mAm.updateOomAdjLocked();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001408
1409 boolean created = false;
1410 try {
Dianne Hackborncf1171642013-07-12 17:26:02 -07001411 String nameTerm;
1412 int lastPeriod = r.shortName.lastIndexOf('.');
1413 nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
Jeff Sharkey9d6d8902012-11-09 17:32:43 -08001414 EventLogTags.writeAmCreateService(
Dianne Hackborncf1171642013-07-12 17:26:02 -07001415 r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001416 synchronized (r.stats.getBatteryStats()) {
1417 r.stats.startLaunchedLocked();
1418 }
1419 mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborna413dc02013-07-12 12:02:55 -07001420 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001421 app.thread.scheduleCreateService(r, r.serviceInfo,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001422 mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
1423 app.repProcState);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001424 r.postNotification();
1425 created = true;
1426 } finally {
1427 if (!created) {
1428 app.services.remove(r);
Dianne Hackbornbc72dce2013-11-11 10:43:38 -08001429 r.app = null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001430 scheduleServiceRestartLocked(r, false);
1431 }
1432 }
1433
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001434 requestServiceBindingsLocked(r, execInFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001435
1436 // If the service is in the started state, and there are no
1437 // pending arguments, then fake up one so its onStartCommand() will
1438 // be called.
1439 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
1440 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
1441 null, null));
1442 }
1443
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001444 sendServiceArgsLocked(r, execInFg, true);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001445
1446 if (r.delayed) {
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08001447 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "REM FR DELAY LIST (new proc): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001448 getServiceMap(r.userId).mDelayedStartList.remove(r);
1449 r.delayed = false;
1450 }
1451
1452 if (r.delayedStop) {
1453 // Oh and hey we've already been asked to stop!
1454 r.delayedStop = false;
1455 if (r.startRequested) {
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08001456 if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Applying delayed stop (from start): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001457 stopServiceLocked(r);
1458 }
1459 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001460 }
1461
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001462 private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001463 boolean oomAdjusted) {
1464 final int N = r.pendingStarts.size();
1465 if (N == 0) {
1466 return;
1467 }
1468
1469 while (r.pendingStarts.size() > 0) {
1470 try {
1471 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
1472 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
1473 + r + " " + r.intent + " args=" + si.intent);
1474 if (si.intent == null && N > 1) {
1475 // If somehow we got a dummy null intent in the middle,
1476 // then skip it. DO NOT skip a null intent when it is
1477 // the only one in the list -- this is to support the
1478 // onStartCommand(null) case.
1479 continue;
1480 }
1481 si.deliveredTime = SystemClock.uptimeMillis();
1482 r.deliveredStarts.add(si);
1483 si.deliveryCount++;
1484 if (si.neededGrants != null) {
1485 mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
1486 si.getUriPermissionsLocked());
1487 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001488 bumpServiceExecutingLocked(r, execInFg, "start");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001489 if (!oomAdjusted) {
1490 oomAdjusted = true;
1491 mAm.updateOomAdjLocked(r.app);
1492 }
1493 int flags = 0;
1494 if (si.deliveryCount > 1) {
1495 flags |= Service.START_FLAG_RETRY;
1496 }
1497 if (si.doneExecutingCount > 0) {
1498 flags |= Service.START_FLAG_REDELIVERY;
1499 }
1500 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
1501 } catch (RemoteException e) {
1502 // Remote process gone... we'll let the normal cleanup take
1503 // care of this.
1504 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
1505 break;
1506 } catch (Exception e) {
1507 Slog.w(TAG, "Unexpected exception", e);
1508 break;
1509 }
1510 }
1511 }
1512
Dianne Hackborn164371f2013-10-01 19:10:13 -07001513 private final boolean isServiceNeeded(ServiceRecord r, boolean knowConn, boolean hasConn) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001514 // Are we still explicitly being asked to run?
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001515 if (r.startRequested) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001516 return true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001517 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001518
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001519 // Is someone still bound to us keepign us running?
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001520 if (!knowConn) {
1521 hasConn = r.hasAutoCreateConnections();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001522 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001523 if (hasConn) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001524 return true;
1525 }
1526
1527 return false;
1528 }
1529
1530 private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
1531 boolean hasConn) {
1532 //Slog.i(TAG, "Bring down service:");
1533 //r.dump(" ");
1534
1535 if (isServiceNeeded(r, knowConn, hasConn)) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001536 return;
1537 }
1538
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001539 // Are we in the process of launching?
1540 if (mPendingServices.contains(r)) {
1541 return;
1542 }
1543
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001544 bringDownServiceLocked(r);
1545 }
1546
1547 private final void bringDownServiceLocked(ServiceRecord r) {
1548 //Slog.i(TAG, "Bring down service:");
1549 //r.dump(" ");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001550
Dianne Hackborn390517b2013-05-30 15:03:32 -07001551 // Report to all of the connections that the service is no longer
1552 // available.
1553 for (int conni=r.connections.size()-1; conni>=0; conni--) {
1554 ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
1555 for (int i=0; i<c.size(); i++) {
1556 ConnectionRecord cr = c.get(i);
1557 // There is still a connection to the service that is
1558 // being brought down. Mark it as dead.
1559 cr.serviceDead = true;
1560 try {
1561 cr.conn.connected(r.name, null);
1562 } catch (Exception e) {
1563 Slog.w(TAG, "Failure disconnecting service " + r.name +
1564 " to connection " + c.get(i).conn.asBinder() +
1565 " (in " + c.get(i).binding.client.processName + ")", e);
1566 }
1567 }
1568 }
1569
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001570 // Tell the service that it has been unbound.
Dianne Hackborn390517b2013-05-30 15:03:32 -07001571 if (r.app != null && r.app.thread != null) {
1572 for (int i=r.bindings.size()-1; i>=0; i--) {
1573 IntentBindRecord ibr = r.bindings.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001574 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
1575 + ": hasBound=" + ibr.hasBound);
Dianne Hackborn390517b2013-05-30 15:03:32 -07001576 if (ibr.hasBound) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001577 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001578 bumpServiceExecutingLocked(r, false, "bring down unbind");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001579 mAm.updateOomAdjLocked(r.app);
1580 ibr.hasBound = false;
1581 r.app.thread.scheduleUnbindService(r,
1582 ibr.intent.getIntent());
1583 } catch (Exception e) {
1584 Slog.w(TAG, "Exception when unbinding service "
1585 + r.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001586 serviceProcessGoneLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001587 }
1588 }
1589 }
1590 }
1591
1592 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Jeff Sharkey9d6d8902012-11-09 17:32:43 -08001593 EventLogTags.writeAmDestroyService(
1594 r.userId, System.identityHashCode(r), (r.app != null) ? r.app.pid : -1);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001595
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001596 final ServiceMap smap = getServiceMap(r.userId);
1597 smap.mServicesByName.remove(r.name);
1598 smap.mServicesByIntent.remove(r.intent);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001599 r.totalRestartCount = 0;
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001600 unscheduleServiceRestartLocked(r, 0, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001601
1602 // Also make sure it is not on the pending list.
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001603 for (int i=mPendingServices.size()-1; i>=0; i--) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001604 if (mPendingServices.get(i) == r) {
1605 mPendingServices.remove(i);
1606 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001607 }
1608 }
1609
1610 r.cancelNotification();
1611 r.isForeground = false;
1612 r.foregroundId = 0;
1613 r.foregroundNoti = null;
1614
1615 // Clear start entries.
1616 r.clearDeliveredStartsLocked();
1617 r.pendingStarts.clear();
1618
1619 if (r.app != null) {
1620 synchronized (r.stats.getBatteryStats()) {
1621 r.stats.stopLaunchedLocked();
1622 }
1623 r.app.services.remove(r);
1624 if (r.app.thread != null) {
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001625 updateServiceForegroundLocked(r.app, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001626 try {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001627 bumpServiceExecutingLocked(r, false, "destroy");
1628 mDestroyingServices.add(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001629 mAm.updateOomAdjLocked(r.app);
1630 r.app.thread.scheduleStopService(r);
1631 } catch (Exception e) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001632 Slog.w(TAG, "Exception when destroying service "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001633 + r.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001634 serviceProcessGoneLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001635 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001636 } else {
1637 if (DEBUG_SERVICE) Slog.v(
1638 TAG, "Removed service that has no process: " + r);
1639 }
1640 } else {
1641 if (DEBUG_SERVICE) Slog.v(
1642 TAG, "Removed service that is not running: " + r);
1643 }
1644
1645 if (r.bindings.size() > 0) {
1646 r.bindings.clear();
1647 }
1648
1649 if (r.restarter instanceof ServiceRestarter) {
1650 ((ServiceRestarter)r.restarter).setService(null);
1651 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001652
Dianne Hackbornd2932242013-08-05 18:18:42 -07001653 int memFactor = mAm.mProcessStats.getMemFactorLocked();
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001654 long now = SystemClock.uptimeMillis();
1655 if (r.tracker != null) {
1656 r.tracker.setStarted(false, memFactor, now);
1657 r.tracker.setBound(false, memFactor, now);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001658 if (r.executeNesting == 0) {
Dianne Hackborn878deb32013-10-14 16:55:09 -07001659 r.tracker.clearCurrentOwner(r, false);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001660 r.tracker = null;
1661 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001662 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001663
1664 smap.ensureNotStartingBackground(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001665 }
1666
1667 void removeConnectionLocked(
1668 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
1669 IBinder binder = c.conn.asBinder();
1670 AppBindRecord b = c.binding;
1671 ServiceRecord s = b.service;
1672 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
1673 if (clist != null) {
1674 clist.remove(c);
1675 if (clist.size() == 0) {
1676 s.connections.remove(binder);
1677 }
1678 }
1679 b.connections.remove(c);
1680 if (c.activity != null && c.activity != skipAct) {
1681 if (c.activity.connections != null) {
1682 c.activity.connections.remove(c);
1683 }
1684 }
1685 if (b.client != skipApp) {
1686 b.client.connections.remove(c);
1687 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
1688 b.client.updateHasAboveClientLocked();
1689 }
Dianne Hackborndb926082013-10-31 16:32:44 -07001690 if (s.app != null) {
1691 updateServiceClientActivitiesLocked(s.app, c);
1692 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001693 }
1694 clist = mServiceConnections.get(binder);
1695 if (clist != null) {
1696 clist.remove(c);
1697 if (clist.size() == 0) {
1698 mServiceConnections.remove(binder);
1699 }
1700 }
1701
1702 if (b.connections.size() == 0) {
1703 b.intent.apps.remove(b.client);
1704 }
1705
1706 if (!c.serviceDead) {
1707 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
1708 + ": shouldUnbind=" + b.intent.hasBound);
1709 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
1710 && b.intent.hasBound) {
1711 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001712 bumpServiceExecutingLocked(s, false, "unbind");
Dianne Hackborndb926082013-10-31 16:32:44 -07001713 if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0
1714 && s.app.setProcState <= ActivityManager.PROCESS_STATE_RECEIVER) {
1715 // If this service's process is not already in the cached list,
1716 // then update it in the LRU list here because this may be causing
1717 // it to go down there and we want it to start out near the top.
1718 mAm.updateLruProcessLocked(s.app, false, null);
1719 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001720 mAm.updateOomAdjLocked(s.app);
1721 b.intent.hasBound = false;
1722 // Assume the client doesn't want to know about a rebind;
1723 // we will deal with that later if it asks for one.
1724 b.intent.doRebind = false;
1725 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
1726 } catch (Exception e) {
1727 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001728 serviceProcessGoneLocked(s);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001729 }
1730 }
1731
1732 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001733 boolean hasAutoCreate = s.hasAutoCreateConnections();
1734 if (!hasAutoCreate) {
1735 if (s.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001736 s.tracker.setBound(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001737 SystemClock.uptimeMillis());
1738 }
1739 }
1740 bringDownServiceIfNeededLocked(s, true, hasAutoCreate);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001741 }
1742 }
1743 }
1744
1745 void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001746 boolean inDestroying = mDestroyingServices.contains(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001747 if (r != null) {
1748 if (type == 1) {
1749 // This is a call from a service start... take care of
1750 // book-keeping.
1751 r.callStart = true;
1752 switch (res) {
1753 case Service.START_STICKY_COMPATIBILITY:
1754 case Service.START_STICKY: {
1755 // We are done with the associated start arguments.
1756 r.findDeliveredStart(startId, true);
1757 // Don't stop if killed.
1758 r.stopIfKilled = false;
1759 break;
1760 }
1761 case Service.START_NOT_STICKY: {
1762 // We are done with the associated start arguments.
1763 r.findDeliveredStart(startId, true);
1764 if (r.getLastStartId() == startId) {
1765 // There is no more work, and this service
1766 // doesn't want to hang around if killed.
1767 r.stopIfKilled = true;
1768 }
1769 break;
1770 }
1771 case Service.START_REDELIVER_INTENT: {
1772 // We'll keep this item until they explicitly
1773 // call stop for it, but keep track of the fact
1774 // that it was delivered.
1775 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
1776 if (si != null) {
1777 si.deliveryCount = 0;
1778 si.doneExecutingCount++;
1779 // Don't stop if killed.
1780 r.stopIfKilled = true;
1781 }
1782 break;
1783 }
1784 case Service.START_TASK_REMOVED_COMPLETE: {
1785 // Special processing for onTaskRemoved(). Don't
1786 // impact normal onStartCommand() processing.
1787 r.findDeliveredStart(startId, true);
1788 break;
1789 }
1790 default:
1791 throw new IllegalArgumentException(
1792 "Unknown service start result: " + res);
1793 }
1794 if (res == Service.START_STICKY_COMPATIBILITY) {
1795 r.callStart = false;
1796 }
1797 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001798 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn164371f2013-10-01 19:10:13 -07001799 serviceDoneExecutingLocked(r, inDestroying, inDestroying);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001800 Binder.restoreCallingIdentity(origId);
1801 } else {
1802 Slog.w(TAG, "Done executing unknown service from pid "
1803 + Binder.getCallingPid());
1804 }
1805 }
1806
Dianne Hackborn878deb32013-10-14 16:55:09 -07001807 private void serviceProcessGoneLocked(ServiceRecord r) {
1808 if (r.tracker != null) {
1809 int memFactor = mAm.mProcessStats.getMemFactorLocked();
1810 long now = SystemClock.uptimeMillis();
1811 r.tracker.setExecuting(false, memFactor, now);
1812 r.tracker.setBound(false, memFactor, now);
Dianne Hackbornbc72dce2013-11-11 10:43:38 -08001813 r.tracker.setStarted(false, memFactor, now);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001814 }
1815 serviceDoneExecutingLocked(r, true, true);
1816 }
1817
Dianne Hackborn164371f2013-10-01 19:10:13 -07001818 private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
1819 boolean finishing) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001820 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
1821 + ": nesting=" + r.executeNesting
Dianne Hackborn164371f2013-10-01 19:10:13 -07001822 + ", inDestroying=" + inDestroying + ", app=" + r.app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001823 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
1824 r.executeNesting--;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001825 if (r.executeNesting <= 0) {
1826 if (r.app != null) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001827 if (DEBUG_SERVICE) Slog.v(TAG,
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001828 "Nesting at 0 of " + r.shortName);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001829 r.app.execServicesFg = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001830 r.app.executingServices.remove(r);
1831 if (r.app.executingServices.size() == 0) {
1832 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
1833 "No more executingServices of " + r.shortName);
1834 mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001835 } else if (r.executeFg) {
1836 // Need to re-evaluate whether the app still needs to be in the foreground.
1837 for (int i=r.app.executingServices.size()-1; i>=0; i--) {
1838 if (r.app.executingServices.valueAt(i).executeFg) {
1839 r.app.execServicesFg = true;
1840 break;
1841 }
1842 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001843 }
Dianne Hackborn164371f2013-10-01 19:10:13 -07001844 if (inDestroying) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001845 if (DEBUG_SERVICE) Slog.v(TAG,
Dianne Hackborn164371f2013-10-01 19:10:13 -07001846 "doneExecuting remove destroying " + r);
1847 mDestroyingServices.remove(r);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001848 r.bindings.clear();
1849 }
1850 mAm.updateOomAdjLocked(r.app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001851 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001852 r.executeFg = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001853 if (r.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001854 r.tracker.setExecuting(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001855 SystemClock.uptimeMillis());
Dianne Hackborn164371f2013-10-01 19:10:13 -07001856 if (finishing) {
Dianne Hackborn878deb32013-10-14 16:55:09 -07001857 r.tracker.clearCurrentOwner(r, false);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001858 r.tracker = null;
1859 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001860 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001861 if (finishing) {
Dianne Hackborn90e9b1d2013-11-21 12:50:01 -08001862 if (r.app != null && !r.app.persistent) {
Dianne Hackbornddc19e92013-11-14 14:32:17 -08001863 r.app.services.remove(r);
1864 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001865 r.app = null;
1866 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001867 }
1868 }
1869
1870 boolean attachApplicationLocked(ProcessRecord proc, String processName) throws Exception {
1871 boolean didSomething = false;
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001872 // Collect any services that are waiting for this process to come up.
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001873 if (mPendingServices.size() > 0) {
1874 ServiceRecord sr = null;
1875 try {
1876 for (int i=0; i<mPendingServices.size(); i++) {
1877 sr = mPendingServices.get(i);
1878 if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
1879 || !processName.equals(sr.processName))) {
1880 continue;
1881 }
1882
1883 mPendingServices.remove(i);
1884 i--;
Dianne Hackbornd2932242013-08-05 18:18:42 -07001885 proc.addPackage(sr.appInfo.packageName, mAm.mProcessStats);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001886 realStartServiceLocked(sr, proc, sr.createdFromFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001887 didSomething = true;
1888 }
1889 } catch (Exception e) {
1890 Slog.w(TAG, "Exception in new application when starting service "
1891 + sr.shortName, e);
1892 throw e;
1893 }
1894 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001895 // Also, if there are any services that are waiting to restart and
1896 // would run in this process, now is a good time to start them. It would
1897 // be weird to bring up the process but arbitrarily not let the services
1898 // run at this point just because their restart time hasn't come up.
1899 if (mRestartingServices.size() > 0) {
1900 ServiceRecord sr = null;
1901 for (int i=0; i<mRestartingServices.size(); i++) {
1902 sr = mRestartingServices.get(i);
1903 if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
1904 || !processName.equals(sr.processName))) {
1905 continue;
1906 }
1907 mAm.mHandler.removeCallbacks(sr.restarter);
1908 mAm.mHandler.post(sr.restarter);
1909 }
1910 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001911 return didSomething;
1912 }
1913
1914 void processStartTimedOutLocked(ProcessRecord proc) {
1915 for (int i=0; i<mPendingServices.size(); i++) {
1916 ServiceRecord sr = mPendingServices.get(i);
1917 if ((proc.uid == sr.appInfo.uid
1918 && proc.processName.equals(sr.processName))
1919 || sr.isolatedProc == proc) {
1920 Slog.w(TAG, "Forcing bringing down service: " + sr);
1921 sr.isolatedProc = null;
1922 mPendingServices.remove(i);
1923 i--;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001924 bringDownServiceLocked(sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001925 }
1926 }
1927 }
1928
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001929 private boolean collectForceStopServicesLocked(String name, int userId,
1930 boolean evenPersistent, boolean doit,
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001931 ArrayMap<ComponentName, ServiceRecord> services,
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001932 ArrayList<ServiceRecord> result) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001933 boolean didSomething = false;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001934 for (int i=0; i<services.size(); i++) {
1935 ServiceRecord service = services.valueAt(i);
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001936 if ((name == null || service.packageName.equals(name))
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001937 && (service.app == null || evenPersistent || !service.app.persistent)) {
1938 if (!doit) {
1939 return true;
1940 }
1941 didSomething = true;
1942 Slog.i(TAG, " Force stopping service " + service);
1943 if (service.app != null) {
1944 service.app.removed = true;
Dianne Hackborn90e9b1d2013-11-21 12:50:01 -08001945 if (!service.app.persistent) {
1946 service.app.services.remove(service);
1947 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001948 }
1949 service.app = null;
1950 service.isolatedProc = null;
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001951 result.add(service);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001952 }
1953 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001954 return didSomething;
1955 }
1956
1957 boolean forceStopLocked(String name, int userId, boolean evenPersistent, boolean doit) {
1958 boolean didSomething = false;
1959 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
1960 if (userId == UserHandle.USER_ALL) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001961 for (int i=0; i<mServiceMap.size(); i++) {
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001962 didSomething |= collectForceStopServicesLocked(name, userId, evenPersistent,
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001963 doit, mServiceMap.valueAt(i).mServicesByName, services);
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001964 if (!doit && didSomething) {
1965 return true;
1966 }
1967 }
1968 } else {
Amith Yamasani540b6592013-10-01 13:02:52 -07001969 ServiceMap smap = mServiceMap.get(userId);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001970 if (smap != null) {
1971 ArrayMap<ComponentName, ServiceRecord> items = smap.mServicesByName;
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07001972 didSomething = collectForceStopServicesLocked(name, userId, evenPersistent,
1973 doit, items, services);
1974 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001975 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001976
1977 int N = services.size();
1978 for (int i=0; i<N; i++) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001979 bringDownServiceLocked(services.get(i));
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001980 }
1981 return didSomething;
1982 }
1983
1984 void cleanUpRemovedTaskLocked(TaskRecord tr, ComponentName component, Intent baseIntent) {
1985 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001986 ArrayMap<ComponentName, ServiceRecord> alls = getServices(tr.userId);
1987 for (int i=0; i<alls.size(); i++) {
1988 ServiceRecord sr = alls.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001989 if (sr.packageName.equals(component.getPackageName())) {
1990 services.add(sr);
1991 }
1992 }
1993
1994 // Take care of any running services associated with the app.
1995 for (int i=0; i<services.size(); i++) {
1996 ServiceRecord sr = services.get(i);
1997 if (sr.startRequested) {
1998 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
1999 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
2000 stopServiceLocked(sr);
2001 } else {
2002 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
2003 sr.makeNextStartId(), baseIntent, null));
2004 if (sr.app != null && sr.app.thread != null) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002005 // We always run in the foreground, since this is called as
2006 // part of the "remove task" UI operation.
2007 sendServiceArgsLocked(sr, true, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002008 }
2009 }
2010 }
2011 }
2012 }
2013
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002014 final void killServicesLocked(ProcessRecord app, boolean allowRestart) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002015 // Report disconnected services.
2016 if (false) {
2017 // XXX we are letting the client link to the service for
2018 // death notifications.
2019 if (app.services.size() > 0) {
2020 Iterator<ServiceRecord> it = app.services.iterator();
2021 while (it.hasNext()) {
2022 ServiceRecord r = it.next();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002023 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2024 ArrayList<ConnectionRecord> cl = r.connections.valueAt(conni);
2025 for (int i=0; i<cl.size(); i++) {
2026 ConnectionRecord c = cl.get(i);
2027 if (c.binding.client != app) {
2028 try {
2029 //c.conn.connected(r.className, null);
2030 } catch (Exception e) {
2031 // todo: this should be asynchronous!
2032 Slog.w(TAG, "Exception thrown disconnected servce "
2033 + r.shortName
2034 + " from app " + app.processName, e);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002035 }
2036 }
2037 }
2038 }
2039 }
2040 }
2041 }
2042
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002043 // First clear app state from services.
Dianne Hackbornc8230512013-07-13 21:32:12 -07002044 for (int i=app.services.size()-1; i>=0; i--) {
Dianne Hackbornc8230512013-07-13 21:32:12 -07002045 ServiceRecord sr = app.services.valueAt(i);
2046 synchronized (sr.stats.getBatteryStats()) {
2047 sr.stats.stopLaunchedLocked();
2048 }
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08002049 if (sr.app != app && sr.app != null && !sr.app.persistent) {
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002050 sr.app.services.remove(sr);
2051 }
Dianne Hackbornc8230512013-07-13 21:32:12 -07002052 sr.app = null;
2053 sr.isolatedProc = null;
2054 sr.executeNesting = 0;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002055 sr.forceClearTracker();
2056 if (mDestroyingServices.remove(sr)) {
2057 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove destroying " + sr);
Dianne Hackbornc8230512013-07-13 21:32:12 -07002058 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002059
Dianne Hackbornc8230512013-07-13 21:32:12 -07002060 final int numClients = sr.bindings.size();
2061 for (int bindingi=numClients-1; bindingi>=0; bindingi--) {
2062 IntentBindRecord b = sr.bindings.valueAt(bindingi);
2063 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
2064 + ": shouldUnbind=" + b.hasBound);
2065 b.binder = null;
2066 b.requested = b.received = b.hasBound = false;
2067 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002068 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002069
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002070 // Clean up any connections this application has to other services.
2071 for (int i=app.connections.size()-1; i>=0; i--) {
2072 ConnectionRecord r = app.connections.valueAt(i);
2073 removeConnectionLocked(r, app, null);
2074 }
2075 app.connections.clear();
2076
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002077 ServiceMap smap = getServiceMap(app.userId);
2078
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002079 // Now do remaining service cleanup.
2080 for (int i=app.services.size()-1; i>=0; i--) {
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002081 ServiceRecord sr = app.services.valueAt(i);
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08002082
2083 // Unless the process is persistent, this process record is going away,
2084 // so make sure the service is cleaned out of it.
2085 if (!app.persistent) {
Dianne Hackborn4190fc52013-12-09 18:20:16 -08002086 app.services.removeAt(i);
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08002087 }
2088
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002089 // Sanity check: if the service listed for the app is not one
Dianne Hackborn4190fc52013-12-09 18:20:16 -08002090 // we actually are maintaining, just let it drop.
Dianne Hackborn40c87252014-03-19 16:55:40 -07002091 final ServiceRecord curRec = smap.mServicesByName.get(sr.name);
2092 if (curRec != sr) {
2093 if (curRec != null) {
2094 Slog.wtf(TAG, "Service " + sr + " in process " + app
2095 + " not same as in map: " + curRec);
2096 }
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002097 continue;
2098 }
2099
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002100 // Any services running in the application may need to be placed
2101 // back in the pending list.
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002102 if (allowRestart && sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
Dianne Hackbornc8230512013-07-13 21:32:12 -07002103 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
2104 Slog.w(TAG, "Service crashed " + sr.crashCount
2105 + " times, stopping: " + sr);
2106 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
2107 sr.userId, sr.crashCount, sr.shortName, app.pid);
2108 bringDownServiceLocked(sr);
2109 } else if (!allowRestart) {
2110 bringDownServiceLocked(sr);
2111 } else {
2112 boolean canceled = scheduleServiceRestartLocked(sr, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002113
Dianne Hackbornc8230512013-07-13 21:32:12 -07002114 // Should the service remain running? Note that in the
2115 // extreme case of so many attempts to deliver a command
2116 // that it failed we also will stop it here.
2117 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
2118 if (sr.pendingStarts.size() == 0) {
2119 sr.startRequested = false;
2120 if (sr.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07002121 sr.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackbornc8230512013-07-13 21:32:12 -07002122 SystemClock.uptimeMillis());
2123 }
2124 if (!sr.hasAutoCreateConnections()) {
2125 // Whoops, no reason to restart!
2126 bringDownServiceLocked(sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002127 }
2128 }
2129 }
2130 }
Dianne Hackbornc8230512013-07-13 21:32:12 -07002131 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002132
Dianne Hackbornc8230512013-07-13 21:32:12 -07002133 if (!allowRestart) {
2134 app.services.clear();
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002135
2136 // Make sure there are no more restarting services for this process.
2137 for (int i=mRestartingServices.size()-1; i>=0; i--) {
2138 ServiceRecord r = mRestartingServices.get(i);
2139 if (r.processName.equals(app.processName) &&
2140 r.serviceInfo.applicationInfo.uid == app.info.uid) {
2141 mRestartingServices.remove(i);
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08002142 clearRestartingIfNeededLocked(r);
2143 }
2144 }
2145 for (int i=mPendingServices.size()-1; i>=0; i--) {
2146 ServiceRecord r = mPendingServices.get(i);
2147 if (r.processName.equals(app.processName) &&
2148 r.serviceInfo.applicationInfo.uid == app.info.uid) {
2149 mPendingServices.remove(i);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002150 }
2151 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002152 }
2153
2154 // Make sure we have no more records on the stopping list.
Dianne Hackborn164371f2013-10-01 19:10:13 -07002155 int i = mDestroyingServices.size();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002156 while (i > 0) {
2157 i--;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002158 ServiceRecord sr = mDestroyingServices.get(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002159 if (sr.app == app) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07002160 sr.forceClearTracker();
2161 mDestroyingServices.remove(i);
2162 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove destroying " + sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002163 }
2164 }
2165
2166 app.executingServices.clear();
2167 }
2168
2169 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
2170 ActivityManager.RunningServiceInfo info =
2171 new ActivityManager.RunningServiceInfo();
2172 info.service = r.name;
2173 if (r.app != null) {
2174 info.pid = r.app.pid;
2175 }
2176 info.uid = r.appInfo.uid;
2177 info.process = r.processName;
2178 info.foreground = r.isForeground;
2179 info.activeSince = r.createTime;
2180 info.started = r.startRequested;
2181 info.clientCount = r.connections.size();
2182 info.crashCount = r.crashCount;
2183 info.lastActivityTime = r.lastActivity;
2184 if (r.isForeground) {
2185 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
2186 }
2187 if (r.startRequested) {
2188 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
2189 }
2190 if (r.app != null && r.app.pid == ActivityManagerService.MY_PID) {
2191 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
2192 }
2193 if (r.app != null && r.app.persistent) {
2194 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
2195 }
2196
Dianne Hackborn390517b2013-05-30 15:03:32 -07002197 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2198 ArrayList<ConnectionRecord> connl = r.connections.valueAt(conni);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002199 for (int i=0; i<connl.size(); i++) {
2200 ConnectionRecord conn = connl.get(i);
2201 if (conn.clientLabel != 0) {
2202 info.clientPackage = conn.binding.client.info.packageName;
2203 info.clientLabel = conn.clientLabel;
2204 return info;
2205 }
2206 }
2207 }
2208 return info;
2209 }
2210
2211 List<ActivityManager.RunningServiceInfo> getRunningServiceInfoLocked(int maxNum,
2212 int flags) {
2213 ArrayList<ActivityManager.RunningServiceInfo> res
2214 = new ArrayList<ActivityManager.RunningServiceInfo>();
2215
Dianne Hackborn0c380492012-08-20 17:23:30 -07002216 final int uid = Binder.getCallingUid();
2217 final long ident = Binder.clearCallingIdentity();
2218 try {
2219 if (ActivityManager.checkUidPermission(
2220 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2221 uid) == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn1676c852012-09-10 14:52:30 -07002222 int[] users = mAm.getUsersLocked();
2223 for (int ui=0; ui<users.length && res.size() < maxNum; ui++) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002224 ArrayMap<ComponentName, ServiceRecord> alls = getServices(users[ui]);
2225 for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
2226 ServiceRecord sr = alls.valueAt(i);
2227 res.add(makeRunningServiceInfoLocked(sr));
Dianne Hackborn0c380492012-08-20 17:23:30 -07002228 }
2229 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002230
Dianne Hackborn0c380492012-08-20 17:23:30 -07002231 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
2232 ServiceRecord r = mRestartingServices.get(i);
2233 ActivityManager.RunningServiceInfo info =
2234 makeRunningServiceInfoLocked(r);
2235 info.restarting = r.nextRestartTime;
2236 res.add(info);
2237 }
2238 } else {
2239 int userId = UserHandle.getUserId(uid);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002240 ArrayMap<ComponentName, ServiceRecord> alls = getServices(userId);
2241 for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
2242 ServiceRecord sr = alls.valueAt(i);
2243 res.add(makeRunningServiceInfoLocked(sr));
Dianne Hackborn0c380492012-08-20 17:23:30 -07002244 }
2245
2246 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
2247 ServiceRecord r = mRestartingServices.get(i);
2248 if (r.userId == userId) {
2249 ActivityManager.RunningServiceInfo info =
2250 makeRunningServiceInfoLocked(r);
2251 info.restarting = r.nextRestartTime;
2252 res.add(info);
2253 }
2254 }
2255 }
2256 } finally {
2257 Binder.restoreCallingIdentity(ident);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002258 }
2259
2260 return res;
2261 }
2262
2263 public PendingIntent getRunningServiceControlPanelLocked(ComponentName name) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07002264 int userId = UserHandle.getUserId(Binder.getCallingUid());
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002265 ServiceRecord r = getServiceByName(name, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002266 if (r != null) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002267 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2268 ArrayList<ConnectionRecord> conn = r.connections.valueAt(conni);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002269 for (int i=0; i<conn.size(); i++) {
2270 if (conn.get(i).clientIntent != null) {
2271 return conn.get(i).clientIntent;
2272 }
2273 }
2274 }
2275 }
2276 return null;
2277 }
2278
2279 void serviceTimeout(ProcessRecord proc) {
2280 String anrMessage = null;
2281
2282 synchronized(this) {
2283 if (proc.executingServices.size() == 0 || proc.thread == null) {
2284 return;
2285 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002286 long maxTime = SystemClock.uptimeMillis() -
2287 (proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002288 ServiceRecord timeout = null;
2289 long nextTime = 0;
Dianne Hackbornc8230512013-07-13 21:32:12 -07002290 for (int i=proc.executingServices.size()-1; i>=0; i--) {
2291 ServiceRecord sr = proc.executingServices.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002292 if (sr.executingStart < maxTime) {
2293 timeout = sr;
2294 break;
2295 }
2296 if (sr.executingStart > nextTime) {
2297 nextTime = sr.executingStart;
2298 }
2299 }
2300 if (timeout != null && mAm.mLruProcesses.contains(proc)) {
2301 Slog.w(TAG, "Timeout executing service: " + timeout);
2302 anrMessage = "Executing service " + timeout.shortName;
2303 } else {
2304 Message msg = mAm.mHandler.obtainMessage(
2305 ActivityManagerService.SERVICE_TIMEOUT_MSG);
2306 msg.obj = proc;
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002307 mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg
Dianne Hackborn2be00932013-09-22 16:46:00 -07002308 ? (nextTime+SERVICE_TIMEOUT) : (nextTime + SERVICE_BACKGROUND_TIMEOUT));
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002309 }
2310 }
2311
2312 if (anrMessage != null) {
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -07002313 mAm.appNotResponding(proc, null, null, false, anrMessage);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002314 }
2315 }
2316
Dianne Hackborn2be00932013-09-22 16:46:00 -07002317 void scheduleServiceTimeoutLocked(ProcessRecord proc) {
2318 if (proc.executingServices.size() == 0 || proc.thread == null) {
2319 return;
2320 }
2321 long now = SystemClock.uptimeMillis();
2322 Message msg = mAm.mHandler.obtainMessage(
2323 ActivityManagerService.SERVICE_TIMEOUT_MSG);
2324 msg.obj = proc;
2325 mAm.mHandler.sendMessageAtTime(msg,
2326 proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
2327 }
2328
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002329 /**
2330 * Prints a list of ServiceRecords (dumpsys activity services)
2331 */
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002332 void dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002333 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
2334 boolean needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002335 boolean printedAnything = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002336
2337 ItemMatcher matcher = new ItemMatcher();
2338 matcher.build(args, opti);
2339
2340 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
2341 try {
Dianne Hackborn1676c852012-09-10 14:52:30 -07002342 int[] users = mAm.getUsersLocked();
2343 for (int user : users) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002344 ServiceMap smap = getServiceMap(user);
2345 boolean printed = false;
2346 if (smap.mServicesByName.size() > 0) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002347 long nowReal = SystemClock.elapsedRealtime();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002348 needSep = false;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002349 for (int si=0; si<smap.mServicesByName.size(); si++) {
2350 ServiceRecord r = smap.mServicesByName.valueAt(si);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002351 if (!matcher.match(r, r.name)) {
2352 continue;
2353 }
2354 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2355 continue;
2356 }
2357 if (!printed) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002358 if (printedAnything) {
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07002359 pw.println();
2360 }
Dianne Hackborn1676c852012-09-10 14:52:30 -07002361 pw.println(" User " + user + " active services:");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002362 printed = true;
2363 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002364 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002365 if (needSep) {
2366 pw.println();
2367 }
2368 pw.print(" * ");
2369 pw.println(r);
2370 if (dumpAll) {
2371 r.dump(pw, " ");
2372 needSep = true;
2373 } else {
2374 pw.print(" app=");
2375 pw.println(r.app);
2376 pw.print(" created=");
2377 TimeUtils.formatDuration(r.createTime, nowReal, pw);
2378 pw.print(" started=");
2379 pw.print(r.startRequested);
2380 pw.print(" connections=");
2381 pw.println(r.connections.size());
2382 if (r.connections.size() > 0) {
2383 pw.println(" Connections:");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002384 for (int conni=0; conni<r.connections.size(); conni++) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002385 ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002386 for (int i = 0; i < clist.size(); i++) {
2387 ConnectionRecord conn = clist.get(i);
2388 pw.print(" ");
2389 pw.print(conn.binding.intent.intent.getIntent()
2390 .toShortString(false, false, false, false));
2391 pw.print(" -> ");
2392 ProcessRecord proc = conn.binding.client;
2393 pw.println(proc != null ? proc.toShortString() : "null");
2394 }
2395 }
2396 }
2397 }
2398 if (dumpClient && r.app != null && r.app.thread != null) {
2399 pw.println(" Client:");
2400 pw.flush();
2401 try {
2402 TransferPipe tp = new TransferPipe();
2403 try {
2404 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(),
2405 r, args);
2406 tp.setBufferPrefix(" ");
2407 // Short timeout, since blocking here can
2408 // deadlock with the application.
2409 tp.go(fd, 2000);
2410 } finally {
2411 tp.kill();
2412 }
2413 } catch (IOException e) {
2414 pw.println(" Failure while dumping the service: " + e);
2415 } catch (RemoteException e) {
2416 pw.println(" Got a RemoteException while dumping the service");
2417 }
2418 needSep = true;
2419 }
2420 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002421 needSep |= printed;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002422 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002423 printed = false;
2424 for (int si=0, SN=smap.mDelayedStartList.size(); si<SN; si++) {
2425 ServiceRecord r = smap.mDelayedStartList.get(si);
2426 if (!matcher.match(r, r.name)) {
2427 continue;
2428 }
2429 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2430 continue;
2431 }
2432 if (!printed) {
2433 if (printedAnything) {
2434 pw.println();
2435 }
2436 pw.println(" User " + user + " delayed start services:");
2437 printed = true;
2438 }
2439 printedAnything = true;
2440 pw.print(" * Delayed start "); pw.println(r);
2441 }
2442 printed = false;
2443 for (int si=0, SN=smap.mStartingBackground.size(); si<SN; si++) {
2444 ServiceRecord r = smap.mStartingBackground.get(si);
2445 if (!matcher.match(r, r.name)) {
2446 continue;
2447 }
2448 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2449 continue;
2450 }
2451 if (!printed) {
2452 if (printedAnything) {
2453 pw.println();
2454 }
2455 pw.println(" User " + user + " starting in background:");
2456 printed = true;
2457 }
2458 printedAnything = true;
2459 pw.print(" * Starting bg "); pw.println(r);
2460 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002461 }
Amith Yamasani258848d2012-08-10 17:06:33 -07002462 } catch (Exception e) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002463 Slog.w(TAG, "Exception in dumpServicesLocked", e);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002464 }
2465
2466 if (mPendingServices.size() > 0) {
2467 boolean printed = false;
2468 for (int i=0; i<mPendingServices.size(); i++) {
2469 ServiceRecord r = mPendingServices.get(i);
2470 if (!matcher.match(r, r.name)) {
2471 continue;
2472 }
2473 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2474 continue;
2475 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002476 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002477 if (!printed) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002478 if (needSep) pw.println();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002479 needSep = true;
2480 pw.println(" Pending services:");
2481 printed = true;
2482 }
2483 pw.print(" * Pending "); pw.println(r);
2484 r.dump(pw, " ");
2485 }
2486 needSep = true;
2487 }
2488
2489 if (mRestartingServices.size() > 0) {
2490 boolean printed = false;
2491 for (int i=0; i<mRestartingServices.size(); i++) {
2492 ServiceRecord r = mRestartingServices.get(i);
2493 if (!matcher.match(r, r.name)) {
2494 continue;
2495 }
2496 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2497 continue;
2498 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002499 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002500 if (!printed) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002501 if (needSep) pw.println();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002502 needSep = true;
2503 pw.println(" Restarting services:");
2504 printed = true;
2505 }
2506 pw.print(" * Restarting "); pw.println(r);
2507 r.dump(pw, " ");
2508 }
2509 needSep = true;
2510 }
2511
Dianne Hackborn164371f2013-10-01 19:10:13 -07002512 if (mDestroyingServices.size() > 0) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002513 boolean printed = false;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002514 for (int i=0; i< mDestroyingServices.size(); i++) {
2515 ServiceRecord r = mDestroyingServices.get(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002516 if (!matcher.match(r, r.name)) {
2517 continue;
2518 }
2519 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2520 continue;
2521 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002522 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002523 if (!printed) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002524 if (needSep) pw.println();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002525 needSep = true;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002526 pw.println(" Destroying services:");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002527 printed = true;
2528 }
Dianne Hackborn164371f2013-10-01 19:10:13 -07002529 pw.print(" * Destroy "); pw.println(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002530 r.dump(pw, " ");
2531 }
2532 needSep = true;
2533 }
2534
2535 if (dumpAll) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002536 boolean printed = false;
2537 for (int ic=0; ic<mServiceConnections.size(); ic++) {
2538 ArrayList<ConnectionRecord> r = mServiceConnections.valueAt(ic);
2539 for (int i=0; i<r.size(); i++) {
2540 ConnectionRecord cr = r.get(i);
2541 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
2542 continue;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002543 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002544 if (dumpPackage != null && (cr.binding.client == null
2545 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
2546 continue;
2547 }
2548 printedAnything = true;
2549 if (!printed) {
2550 if (needSep) pw.println();
2551 needSep = true;
2552 pw.println(" Connection bindings to services:");
2553 printed = true;
2554 }
2555 pw.print(" * "); pw.println(cr);
2556 cr.dump(pw, " ");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002557 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002558 }
2559 }
2560
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002561 if (!printedAnything) {
2562 pw.println(" (nothing)");
2563 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002564 }
2565
2566 /**
2567 * There are three ways to call this:
2568 * - no service specified: dump all the services
2569 * - a flattened component name that matched an existing service was specified as the
2570 * first arg: dump that one service
2571 * - the first arg isn't the flattened component name of an existing service:
2572 * dump all services whose component contains the first arg as a substring
2573 */
2574 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
2575 int opti, boolean dumpAll) {
2576 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
2577
Dianne Hackborn1676c852012-09-10 14:52:30 -07002578 synchronized (this) {
2579 int[] users = mAm.getUsersLocked();
2580 if ("all".equals(name)) {
2581 for (int user : users) {
Dianne Hackborn13c590d2013-10-07 14:32:00 -07002582 ServiceMap smap = mServiceMap.get(user);
2583 if (smap == null) {
2584 continue;
2585 }
2586 ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002587 for (int i=0; i<alls.size(); i++) {
2588 ServiceRecord r1 = alls.valueAt(i);
Amith Yamasani258848d2012-08-10 17:06:33 -07002589 services.add(r1);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002590 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002591 }
Dianne Hackborn1676c852012-09-10 14:52:30 -07002592 } else {
2593 ComponentName componentName = name != null
2594 ? ComponentName.unflattenFromString(name) : null;
2595 int objectId = 0;
2596 if (componentName == null) {
2597 // Not a '/' separated full component name; maybe an object ID?
2598 try {
2599 objectId = Integer.parseInt(name, 16);
2600 name = null;
2601 componentName = null;
2602 } catch (RuntimeException e) {
2603 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002604 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002605
Dianne Hackborn1676c852012-09-10 14:52:30 -07002606 for (int user : users) {
Dianne Hackborn13c590d2013-10-07 14:32:00 -07002607 ServiceMap smap = mServiceMap.get(user);
2608 if (smap == null) {
2609 continue;
2610 }
2611 ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002612 for (int i=0; i<alls.size(); i++) {
2613 ServiceRecord r1 = alls.valueAt(i);
Amith Yamasani258848d2012-08-10 17:06:33 -07002614 if (componentName != null) {
2615 if (r1.name.equals(componentName)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002616 services.add(r1);
2617 }
Amith Yamasani258848d2012-08-10 17:06:33 -07002618 } else if (name != null) {
2619 if (r1.name.flattenToString().contains(name)) {
2620 services.add(r1);
2621 }
2622 } else if (System.identityHashCode(r1) == objectId) {
2623 services.add(r1);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002624 }
2625 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002626 }
2627 }
2628 }
2629
2630 if (services.size() <= 0) {
2631 return false;
2632 }
2633
2634 boolean needSep = false;
2635 for (int i=0; i<services.size(); i++) {
2636 if (needSep) {
2637 pw.println();
2638 }
2639 needSep = true;
2640 dumpService("", fd, pw, services.get(i), args, dumpAll);
2641 }
2642 return true;
2643 }
2644
2645 /**
2646 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
2647 * there is a thread associated with the service.
2648 */
2649 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
2650 final ServiceRecord r, String[] args, boolean dumpAll) {
2651 String innerPrefix = prefix + " ";
2652 synchronized (this) {
2653 pw.print(prefix); pw.print("SERVICE ");
2654 pw.print(r.shortName); pw.print(" ");
2655 pw.print(Integer.toHexString(System.identityHashCode(r)));
2656 pw.print(" pid=");
2657 if (r.app != null) pw.println(r.app.pid);
2658 else pw.println("(not running)");
2659 if (dumpAll) {
2660 r.dump(pw, innerPrefix);
2661 }
2662 }
2663 if (r.app != null && r.app.thread != null) {
2664 pw.print(prefix); pw.println(" Client:");
2665 pw.flush();
2666 try {
2667 TransferPipe tp = new TransferPipe();
2668 try {
2669 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
2670 tp.setBufferPrefix(prefix + " ");
2671 tp.go(fd);
2672 } finally {
2673 tp.kill();
2674 }
2675 } catch (IOException e) {
2676 pw.println(prefix + " Failure while dumping the service: " + e);
2677 } catch (RemoteException e) {
2678 pw.println(prefix + " Got a RemoteException while dumping the service");
2679 }
2680 }
2681 }
2682
2683}