blob: ea0b978a9c32a12ab48e550d56123b40f2ad1933 [file] [log] [blame]
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import java.io.FileDescriptor;
20import java.io.IOException;
21import java.io.PrintWriter;
22import java.util.ArrayList;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070023import java.util.HashSet;
24import java.util.Iterator;
25import java.util.List;
26
Dianne Hackborn9210bc82013-09-05 12:31:16 -070027import android.os.Handler;
Dianne Hackborn13c590d2013-10-07 14:32:00 -070028import android.os.Looper;
Dianne Hackborn23037412013-11-04 18:11:29 -080029import android.os.SystemProperties;
Dianne Hackborn9210bc82013-09-05 12:31:16 -070030import android.util.ArrayMap;
Dianne Hackbornd2932242013-08-05 18:18:42 -070031import com.android.internal.app.ProcessStats;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070032import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070033import com.android.internal.os.TransferPipe;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070034import com.android.server.am.ActivityManagerService.ItemMatcher;
35import com.android.server.am.ActivityManagerService.NeededUriGrants;
36
37import android.app.ActivityManager;
38import android.app.AppGlobals;
39import android.app.IApplicationThread;
40import android.app.IServiceConnection;
41import android.app.Notification;
42import android.app.PendingIntent;
43import android.app.Service;
44import android.content.ComponentName;
45import android.content.Context;
46import android.content.Intent;
47import android.content.pm.ApplicationInfo;
48import android.content.pm.PackageManager;
49import android.content.pm.ResolveInfo;
50import android.content.pm.ServiceInfo;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070051import android.os.Binder;
52import android.os.IBinder;
53import android.os.Message;
54import android.os.Process;
55import android.os.RemoteException;
56import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070057import android.os.UserHandle;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070058import android.util.EventLog;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070059import android.util.Slog;
60import android.util.SparseArray;
61import android.util.TimeUtils;
62
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -070063public final class ActiveServices {
Dianne Hackborn599db5c2012-08-03 19:28:48 -070064 static final boolean DEBUG_SERVICE = ActivityManagerService.DEBUG_SERVICE;
65 static final boolean DEBUG_SERVICE_EXECUTING = ActivityManagerService.DEBUG_SERVICE_EXECUTING;
Dianne Hackborn9210bc82013-09-05 12:31:16 -070066 static final boolean DEBUG_DELAYED_SERVICE = ActivityManagerService.DEBUG_SERVICE;
67 static final boolean DEBUG_DELAYED_STATS = DEBUG_DELAYED_SERVICE;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070068 static final boolean DEBUG_MU = ActivityManagerService.DEBUG_MU;
69 static final String TAG = ActivityManagerService.TAG;
70 static final String TAG_MU = ActivityManagerService.TAG_MU;
71
72 // How long we wait for a service to finish executing.
73 static final int SERVICE_TIMEOUT = 20*1000;
74
Dianne Hackbornbf36ee22013-07-26 18:24:10 -070075 // How long we wait for a service to finish executing.
76 static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
77
Dianne Hackborn599db5c2012-08-03 19:28:48 -070078 // How long a service needs to be running until restarting its process
79 // is no longer considered to be a relaunch of the service.
Dianne Hackborn7b492722013-11-01 09:58:45 -070080 static final int SERVICE_RESTART_DURATION = 1*1000;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070081
82 // How long a service needs to be running until it will start back at
83 // SERVICE_RESTART_DURATION after being killed.
84 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
85
86 // Multiplying factor to increase restart duration time by, for each time
87 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
88 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
89
90 // The minimum amount of time between restarting services that we allow.
91 // That is, when multiple services are restarting, we won't allow each
92 // to restart less than this amount of time from the last one.
93 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
94
95 // Maximum amount of time for there to be no activity on a service before
96 // we consider it non-essential and allow its process to go on the
97 // LRU background list.
98 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
99
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700100 // How long we wait for a background started service to stop itself before
101 // allowing the next pending start to run.
102 static final int BG_START_TIMEOUT = 15*1000;
103
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700104 final ActivityManagerService mAm;
105
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700106 // Maximum number of services that we allow to start in the background
107 // at the same time.
108 final int mMaxStartingBackground;
109
110 final SparseArray<ServiceMap> mServiceMap = new SparseArray<ServiceMap>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700111
112 /**
113 * All currently bound service connections. Keys are the IBinder of
114 * the client's IServiceConnection.
115 */
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700116 final ArrayMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
117 = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700118
119 /**
120 * List of services that we have been asked to start,
121 * but haven't yet been able to. It is used to hold start requests
122 * while waiting for their corresponding application thread to get
123 * going.
124 */
125 final ArrayList<ServiceRecord> mPendingServices
126 = new ArrayList<ServiceRecord>();
127
128 /**
129 * List of services that are scheduled to restart following a crash.
130 */
131 final ArrayList<ServiceRecord> mRestartingServices
132 = new ArrayList<ServiceRecord>();
133
134 /**
Dianne Hackborn164371f2013-10-01 19:10:13 -0700135 * List of services that are in the process of being destroyed.
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700136 */
Dianne Hackborn164371f2013-10-01 19:10:13 -0700137 final ArrayList<ServiceRecord> mDestroyingServices
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700138 = new ArrayList<ServiceRecord>();
139
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700140 static final class DelayingProcess extends ArrayList<ServiceRecord> {
141 long timeoout;
142 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700143
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700144 /**
145 * Information about services for a single user.
146 */
147 class ServiceMap extends Handler {
Dianne Hackborn6285a322013-09-18 12:09:47 -0700148 final int mUserId;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700149 final ArrayMap<ComponentName, ServiceRecord> mServicesByName
150 = new ArrayMap<ComponentName, ServiceRecord>();
151 final ArrayMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent
152 = new ArrayMap<Intent.FilterComparison, ServiceRecord>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700153
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700154 final ArrayList<ServiceRecord> mDelayedStartList
155 = new ArrayList<ServiceRecord>();
156 /* XXX eventually I'd like to have this based on processes instead of services.
157 * That is, if we try to start two services in a row both running in the same
158 * process, this should be one entry in mStartingBackground for that one process
159 * that remains until all services in it are done.
160 final ArrayMap<ProcessRecord, DelayingProcess> mStartingBackgroundMap
161 = new ArrayMap<ProcessRecord, DelayingProcess>();
162 final ArrayList<DelayingProcess> mStartingProcessList
163 = new ArrayList<DelayingProcess>();
164 */
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700165
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700166 final ArrayList<ServiceRecord> mStartingBackground
167 = new ArrayList<ServiceRecord>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700168
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700169 static final int MSG_BG_START_TIMEOUT = 1;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700170
Dianne Hackborn13c590d2013-10-07 14:32:00 -0700171 ServiceMap(Looper looper, int userId) {
172 super(looper);
Dianne Hackborn6285a322013-09-18 12:09:47 -0700173 mUserId = userId;
174 }
175
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700176 @Override
177 public void handleMessage(Message msg) {
178 switch (msg.what) {
179 case MSG_BG_START_TIMEOUT: {
180 synchronized (mAm) {
181 rescheduleDelayedStarts();
182 }
183 } break;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700184 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700185 }
186
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700187 void ensureNotStartingBackground(ServiceRecord r) {
188 if (mStartingBackground.remove(r)) {
189 if (DEBUG_DELAYED_STATS) Slog.v(TAG, "No longer background starting: " + r);
190 rescheduleDelayedStarts();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700191 }
Dianne Hackborn2e46bb52013-09-13 17:01:26 -0700192 if (mDelayedStartList.remove(r)) {
193 if (DEBUG_DELAYED_STATS) Slog.v(TAG, "No longer delaying start: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700194 }
195 }
196
197 void rescheduleDelayedStarts() {
198 removeMessages(MSG_BG_START_TIMEOUT);
199 final long now = SystemClock.uptimeMillis();
200 for (int i=0, N=mStartingBackground.size(); i<N; i++) {
201 ServiceRecord r = mStartingBackground.get(i);
202 if (r.startingBgTimeout <= now) {
203 Slog.i(TAG, "Waited long enough for: " + r);
204 mStartingBackground.remove(i);
205 N--;
206 }
207 }
208 while (mDelayedStartList.size() > 0
209 && mStartingBackground.size() < mMaxStartingBackground) {
210 ServiceRecord r = mDelayedStartList.remove(0);
211 if (DEBUG_DELAYED_STATS) Slog.v(TAG, "REM FR DELAY LIST (exec next): " + r);
212 if (r.pendingStarts.size() <= 0) {
213 Slog.w(TAG, "**** NO PENDING STARTS! " + r + " startReq=" + r.startRequested
214 + " delayedStop=" + r.delayedStop);
215 }
216 if (DEBUG_DELAYED_SERVICE) {
217 if (mDelayedStartList.size() > 0) {
218 Slog.v(TAG, "Remaining delayed list:");
219 for (int i=0; i<mDelayedStartList.size(); i++) {
220 Slog.v(TAG, " #" + i + ": " + mDelayedStartList.get(i));
221 }
222 }
223 }
224 r.delayed = false;
225 startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false, true);
226 }
227 if (mStartingBackground.size() > 0) {
228 ServiceRecord next = mStartingBackground.get(0);
229 long when = next.startingBgTimeout > now ? next.startingBgTimeout : now;
230 if (DEBUG_DELAYED_SERVICE) Slog.v(TAG, "Top bg start is " + next
231 + ", can delay others up to " + when);
232 Message msg = obtainMessage(MSG_BG_START_TIMEOUT);
233 sendMessageAtTime(msg, when);
234 }
Dianne Hackborn6285a322013-09-18 12:09:47 -0700235 if (mStartingBackground.size() < mMaxStartingBackground) {
236 mAm.backgroundServicesFinishedLocked(mUserId);
237 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700238 }
239 }
240
241 public ActiveServices(ActivityManagerService service) {
242 mAm = service;
Dianne Hackborn23037412013-11-04 18:11:29 -0800243 int maxBg = 0;
244 try {
245 maxBg = Integer.parseInt(SystemProperties.get("ro.config.max_starting_bg", "0"));
246 } catch(RuntimeException e) {
247 }
248 mMaxStartingBackground = maxBg > 0 ? maxBg : ActivityManager.isLowRamDeviceStatic() ? 1 : 3;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700249 }
250
251 ServiceRecord getServiceByName(ComponentName name, int callingUser) {
252 // TODO: Deal with global services
253 if (DEBUG_MU)
254 Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
255 return getServiceMap(callingUser).mServicesByName.get(name);
256 }
257
Dianne Hackborn6285a322013-09-18 12:09:47 -0700258 boolean hasBackgroundServices(int callingUser) {
259 ServiceMap smap = mServiceMap.get(callingUser);
260 return smap != null ? smap.mStartingBackground.size() >= mMaxStartingBackground : false;
261 }
262
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700263 private ServiceMap getServiceMap(int callingUser) {
264 ServiceMap smap = mServiceMap.get(callingUser);
265 if (smap == null) {
Dianne Hackborn13c590d2013-10-07 14:32:00 -0700266 smap = new ServiceMap(mAm.mHandler.getLooper(), callingUser);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700267 mServiceMap.put(callingUser, smap);
268 }
269 return smap;
270 }
271
272 ArrayMap<ComponentName, ServiceRecord> getServices(int callingUser) {
273 return getServiceMap(callingUser).mServicesByName;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700274 }
275
276 ComponentName startServiceLocked(IApplicationThread caller,
277 Intent service, String resolvedType,
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700278 int callingPid, int callingUid, int userId) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700279 if (DEBUG_DELAYED_STATS) Slog.v(TAG, "startService: " + service
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700280 + " type=" + resolvedType + " args=" + service.getExtras());
281
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700282 final boolean callerFg;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700283 if (caller != null) {
284 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
285 if (callerApp == null) {
286 throw new SecurityException(
287 "Unable to find app for caller " + caller
288 + " (pid=" + Binder.getCallingPid()
289 + ") when starting service " + service);
290 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700291 callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
292 } else {
293 callerFg = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700294 }
295
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700296
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700297 ServiceLookupResult res =
298 retrieveServiceLocked(service, resolvedType,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700299 callingPid, callingUid, userId, true, callerFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700300 if (res == null) {
301 return null;
302 }
303 if (res.record == null) {
304 return new ComponentName("!", res.permission != null
305 ? res.permission : "private to package");
306 }
307 ServiceRecord r = res.record;
308 NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
309 callingUid, r.packageName, service, service.getFlags(), null);
Dianne Hackborn7b492722013-11-01 09:58:45 -0700310 if (unscheduleServiceRestartLocked(r, callingUid)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700311 if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
312 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700313 r.lastActivity = SystemClock.uptimeMillis();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700314 r.startRequested = true;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700315 r.delayedStop = false;
316 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
317 service, neededGrants));
318
319 final ServiceMap smap = getServiceMap(r.userId);
320 boolean addToStarting = false;
321 if (!callerFg && r.app == null && mAm.mStartedUsers.get(r.userId) != null) {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700322 ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700323 if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700324 // If this is not coming from a foreground caller, then we may want
325 // to delay the start if there are already other background services
326 // that are starting. This is to avoid process start spam when lots
327 // of applications are all handling things like connectivity broadcasts.
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700328 // We only do this for cached processes, because otherwise an application
329 // can have assumptions about calling startService() for a service to run
330 // in its own process, and for that process to not be killed before the
331 // service is started. This is especially the case for receivers, which
332 // may start a service in onReceive() to do some additional work and have
333 // initialized some global state as part of that.
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700334 if (DEBUG_DELAYED_SERVICE) Slog.v(TAG, "Potential start delay of " + r + " in "
335 + proc);
336 if (r.delayed) {
337 // This service is already scheduled for a delayed start; just leave
338 // it still waiting.
339 if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Continuing to delay: " + r);
340 return r.name;
341 }
342 if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
343 // Something else is starting, delay!
344 Slog.i(TAG, "Delaying start of: " + r);
345 smap.mDelayedStartList.add(r);
346 r.delayed = true;
347 return r.name;
348 }
349 if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Not delaying: " + r);
350 addToStarting = true;
351 } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
352 // We slightly loosen when we will enqueue this new service as a background
353 // starting service we are waiting for, to also include processes that are
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700354 // currently running other services or receivers.
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700355 addToStarting = true;
356 if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Not delaying, but counting as bg: " + r);
357 } else if (DEBUG_DELAYED_STATS) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700358 StringBuilder sb = new StringBuilder(128);
359 sb.append("Not potential delay (state=").append(proc.curProcState)
360 .append(' ').append(proc.adjType);
361 String reason = proc.makeAdjReason();
362 if (reason != null) {
363 sb.append(' ');
364 sb.append(reason);
365 }
366 sb.append("): ");
367 sb.append(r.toString());
368 Slog.v(TAG, sb.toString());
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700369 }
370 } else if (DEBUG_DELAYED_STATS) {
371 if (callerFg) {
372 Slog.v(TAG, "Not potential delay (callerFg=" + callerFg + " uid="
373 + callingUid + " pid=" + callingPid + "): " + r);
374 } else if (r.app != null) {
375 Slog.v(TAG, "Not potential delay (cur app=" + r.app + "): " + r);
376 } else {
377 Slog.v(TAG, "Not potential delay (user " + r.userId + " not started): " + r);
378 }
379 }
380
381 return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
382 }
383
384 ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
385 ServiceRecord r, boolean callerFg, boolean addToStarting) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700386 ProcessStats.ServiceState stracker = r.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -0700387 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700388 stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700389 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700390 r.callStart = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700391 synchronized (r.stats.getBatteryStats()) {
392 r.stats.startRunningLocked();
393 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700394 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -0700395 if (error != null) {
396 return new ComponentName("!!", error);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700397 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700398
399 if (r.startRequested && addToStarting) {
400 boolean first = smap.mStartingBackground.size() == 0;
401 smap.mStartingBackground.add(r);
402 r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
403 if (DEBUG_DELAYED_SERVICE) {
404 RuntimeException here = new RuntimeException("here");
405 here.fillInStackTrace();
406 Slog.v(TAG, "Starting background (first=" + first + "): " + r, here);
407 } else if (DEBUG_DELAYED_STATS) {
408 Slog.v(TAG, "Starting background (first=" + first + "): " + r);
409 }
410 if (first) {
411 smap.rescheduleDelayedStarts();
412 }
413 } else if (callerFg) {
414 smap.ensureNotStartingBackground(r);
415 }
416
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700417 return r.name;
418 }
419
420 private void stopServiceLocked(ServiceRecord service) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700421 if (service.delayed) {
422 // If service isn't actually running, but is is being held in the
423 // delayed list, then we need to keep it started but note that it
424 // should be stopped once no longer delayed.
425 if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Delaying stop of pending: " + service);
426 service.delayedStop = true;
427 return;
428 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700429 synchronized (service.stats.getBatteryStats()) {
430 service.stats.stopRunningLocked();
431 }
432 service.startRequested = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700433 if (service.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700434 service.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700435 SystemClock.uptimeMillis());
436 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700437 service.callStart = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700438 bringDownServiceIfNeededLocked(service, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700439 }
440
441 int stopServiceLocked(IApplicationThread caller, Intent service,
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700442 String resolvedType, int userId) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700443 if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
444 + " type=" + resolvedType);
445
446 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
447 if (caller != null && callerApp == null) {
448 throw new SecurityException(
449 "Unable to find app for caller " + caller
450 + " (pid=" + Binder.getCallingPid()
451 + ") when stopping service " + service);
452 }
453
454 // If this service is active, make sure it is stopped.
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -0700455 ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700456 Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700457 if (r != null) {
458 if (r.record != null) {
459 final long origId = Binder.clearCallingIdentity();
460 try {
461 stopServiceLocked(r.record);
462 } finally {
463 Binder.restoreCallingIdentity(origId);
464 }
465 return 1;
466 }
467 return -1;
468 }
469
470 return 0;
471 }
472
473 IBinder peekServiceLocked(Intent service, String resolvedType) {
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -0700474 ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
475 Binder.getCallingPid(), Binder.getCallingUid(),
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700476 UserHandle.getCallingUserId(), false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700477
478 IBinder ret = null;
479 if (r != null) {
480 // r.record is null if findServiceLocked() failed the caller permission check
481 if (r.record == null) {
482 throw new SecurityException(
483 "Permission Denial: Accessing service " + r.record.name
484 + " from pid=" + Binder.getCallingPid()
485 + ", uid=" + Binder.getCallingUid()
486 + " requires " + r.permission);
487 }
488 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
489 if (ib != null) {
490 ret = ib.binder;
491 }
492 }
493
494 return ret;
495 }
496
497 boolean stopServiceTokenLocked(ComponentName className, IBinder token,
498 int startId) {
499 if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
500 + " " + token + " startId=" + startId);
Dianne Hackborn41203752012-08-31 14:05:51 -0700501 ServiceRecord r = findServiceLocked(className, token, UserHandle.getCallingUserId());
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700502 if (r != null) {
503 if (startId >= 0) {
504 // Asked to only stop if done with all work. Note that
505 // to avoid leaks, we will take this as dropping all
506 // start items up to and including this one.
507 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
508 if (si != null) {
509 while (r.deliveredStarts.size() > 0) {
510 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
511 cur.removeUriPermissionsLocked();
512 if (cur == si) {
513 break;
514 }
515 }
516 }
517
518 if (r.getLastStartId() != startId) {
519 return false;
520 }
521
522 if (r.deliveredStarts.size() > 0) {
523 Slog.w(TAG, "stopServiceToken startId " + startId
524 + " is last, but have " + r.deliveredStarts.size()
525 + " remaining args");
526 }
527 }
528
529 synchronized (r.stats.getBatteryStats()) {
530 r.stats.stopRunningLocked();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700531 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700532 r.startRequested = false;
533 if (r.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700534 r.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700535 SystemClock.uptimeMillis());
536 }
537 r.callStart = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700538 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700539 bringDownServiceIfNeededLocked(r, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700540 Binder.restoreCallingIdentity(origId);
541 return true;
542 }
543 return false;
544 }
545
546 public void setServiceForegroundLocked(ComponentName className, IBinder token,
547 int id, Notification notification, boolean removeNotification) {
Dianne Hackborn41203752012-08-31 14:05:51 -0700548 final int userId = UserHandle.getCallingUserId();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700549 final long origId = Binder.clearCallingIdentity();
550 try {
Dianne Hackborn41203752012-08-31 14:05:51 -0700551 ServiceRecord r = findServiceLocked(className, token, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700552 if (r != null) {
553 if (id != 0) {
554 if (notification == null) {
555 throw new IllegalArgumentException("null notification");
556 }
557 if (r.foregroundId != id) {
558 r.cancelNotification();
559 r.foregroundId = id;
560 }
561 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
562 r.foregroundNoti = notification;
563 r.isForeground = true;
564 r.postNotification();
565 if (r.app != null) {
566 updateServiceForegroundLocked(r.app, true);
567 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700568 getServiceMap(r.userId).ensureNotStartingBackground(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700569 } else {
570 if (r.isForeground) {
571 r.isForeground = false;
572 if (r.app != null) {
Dianne Hackborndb926082013-10-31 16:32:44 -0700573 mAm.updateLruProcessLocked(r.app, false, null);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700574 updateServiceForegroundLocked(r.app, true);
575 }
576 }
577 if (removeNotification) {
578 r.cancelNotification();
579 r.foregroundId = 0;
580 r.foregroundNoti = null;
581 }
582 }
583 }
584 } finally {
585 Binder.restoreCallingIdentity(origId);
586 }
587 }
588
589 private void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
590 boolean anyForeground = false;
Dianne Hackbornc8230512013-07-13 21:32:12 -0700591 for (int i=proc.services.size()-1; i>=0; i--) {
592 ServiceRecord sr = proc.services.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700593 if (sr.isForeground) {
594 anyForeground = true;
595 break;
596 }
597 }
598 if (anyForeground != proc.foregroundServices) {
599 proc.foregroundServices = anyForeground;
600 if (oomAdj) {
601 mAm.updateOomAdjLocked();
602 }
603 }
604 }
605
Dianne Hackborndb926082013-10-31 16:32:44 -0700606 private boolean updateServiceClientActivitiesLocked(ProcessRecord proc,
607 ConnectionRecord modCr) {
608 if (modCr != null && modCr.binding.client != null) {
609 if (modCr.binding.client.activities.size() <= 0) {
610 // This connection is from a client without activities, so adding
611 // and removing is not interesting.
612 return false;
613 }
614 }
615
616 boolean anyClientActivities = false;
617 for (int i=proc.services.size()-1; i>=0 && !anyClientActivities; i--) {
618 ServiceRecord sr = proc.services.valueAt(i);
619 for (int conni=sr.connections.size()-1; conni>=0 && !anyClientActivities; conni--) {
620 ArrayList<ConnectionRecord> clist = sr.connections.valueAt(conni);
621 for (int cri=clist.size()-1; cri>=0; cri--) {
622 ConnectionRecord cr = clist.get(cri);
623 if (cr.binding.client == null || cr.binding.client == proc) {
624 // Binding to ourself is not interesting.
625 continue;
626 }
627 if (cr.binding.client.activities.size() > 0) {
628 anyClientActivities = true;
629 break;
630 }
631 }
632 }
633 }
634 if (anyClientActivities != proc.hasClientActivities) {
635 proc.hasClientActivities = anyClientActivities;
636 mAm.updateLruProcessLocked(proc, anyClientActivities, null);
637 return true;
638 }
639 return false;
640 }
641
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700642 int bindServiceLocked(IApplicationThread caller, IBinder token,
643 Intent service, String resolvedType,
644 IServiceConnection connection, int flags, int userId) {
645 if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
646 + " type=" + resolvedType + " conn=" + connection.asBinder()
647 + " flags=0x" + Integer.toHexString(flags));
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700648 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
649 if (callerApp == null) {
650 throw new SecurityException(
651 "Unable to find app for caller " + caller
652 + " (pid=" + Binder.getCallingPid()
653 + ") when binding service " + service);
654 }
655
656 ActivityRecord activity = null;
657 if (token != null) {
Craig Mautnerd2328952013-03-05 12:46:26 -0800658 activity = ActivityRecord.isInStackLocked(token);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700659 if (activity == null) {
660 Slog.w(TAG, "Binding with unknown activity: " + token);
661 return 0;
662 }
663 }
664
665 int clientLabel = 0;
666 PendingIntent clientIntent = null;
667
668 if (callerApp.info.uid == Process.SYSTEM_UID) {
669 // Hacky kind of thing -- allow system stuff to tell us
670 // what they are, so we can report this elsewhere for
671 // others to know why certain services are running.
672 try {
673 clientIntent = (PendingIntent)service.getParcelableExtra(
674 Intent.EXTRA_CLIENT_INTENT);
675 } catch (RuntimeException e) {
676 }
677 if (clientIntent != null) {
678 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
679 if (clientLabel != 0) {
680 // There are no useful extras in the intent, trash them.
681 // System code calling with this stuff just needs to know
682 // this will happen.
683 service = service.cloneFilter();
684 }
685 }
686 }
687
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700688 final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
689
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700690 ServiceLookupResult res =
691 retrieveServiceLocked(service, resolvedType,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700692 Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700693 if (res == null) {
694 return 0;
695 }
696 if (res.record == null) {
697 return -1;
698 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700699 ServiceRecord s = res.record;
700
701 final long origId = Binder.clearCallingIdentity();
702
703 try {
Dianne Hackborn7b492722013-11-01 09:58:45 -0700704 if (unscheduleServiceRestartLocked(s, callerApp.info.uid)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700705 if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
706 + s);
707 }
708
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700709 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
710 s.lastActivity = SystemClock.uptimeMillis();
711 if (!s.hasAutoCreateConnections()) {
712 // This is the first binding, let the tracker know.
Dianne Hackbornd2932242013-08-05 18:18:42 -0700713 ProcessStats.ServiceState stracker = s.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -0700714 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700715 stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700716 s.lastActivity);
717 }
718 }
719 }
720
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700721 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
722 ConnectionRecord c = new ConnectionRecord(b, activity,
723 connection, flags, clientLabel, clientIntent);
724
725 IBinder binder = connection.asBinder();
726 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
727 if (clist == null) {
728 clist = new ArrayList<ConnectionRecord>();
729 s.connections.put(binder, clist);
730 }
731 clist.add(c);
732 b.connections.add(c);
733 if (activity != null) {
734 if (activity.connections == null) {
735 activity.connections = new HashSet<ConnectionRecord>();
736 }
737 activity.connections.add(c);
738 }
739 b.client.connections.add(c);
740 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
741 b.client.hasAboveClient = true;
742 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700743 if (s.app != null) {
744 updateServiceClientActivitiesLocked(s.app, c);
745 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700746 clist = mServiceConnections.get(binder);
747 if (clist == null) {
748 clist = new ArrayList<ConnectionRecord>();
749 mServiceConnections.put(binder, clist);
750 }
751 clist.add(c);
752
753 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
754 s.lastActivity = SystemClock.uptimeMillis();
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700755 if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700756 return 0;
757 }
758 }
759
760 if (s.app != null) {
761 // This could have made the service more important.
Dianne Hackborndb926082013-10-31 16:32:44 -0700762 mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities, b.client);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700763 mAm.updateOomAdjLocked(s.app);
764 }
765
766 if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
767 + ": received=" + b.intent.received
768 + " apps=" + b.intent.apps.size()
769 + " doRebind=" + b.intent.doRebind);
770
771 if (s.app != null && b.intent.received) {
772 // Service is already running, so we can immediately
773 // publish the connection.
774 try {
775 c.conn.connected(s.name, b.intent.binder);
776 } catch (Exception e) {
777 Slog.w(TAG, "Failure sending service " + s.shortName
778 + " to connection " + c.conn.asBinder()
779 + " (in " + c.binding.client.processName + ")", e);
780 }
781
782 // If this is the first app connected back to this binding,
783 // and the service had previously asked to be told when
784 // rebound, then do so.
785 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700786 requestServiceBindingLocked(s, b.intent, callerFg, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700787 }
788 } else if (!b.intent.requested) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700789 requestServiceBindingLocked(s, b.intent, callerFg, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700790 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700791
792 getServiceMap(s.userId).ensureNotStartingBackground(s);
793
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700794 } finally {
795 Binder.restoreCallingIdentity(origId);
796 }
797
798 return 1;
799 }
800
801 void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
802 final long origId = Binder.clearCallingIdentity();
803 try {
804 if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
805 + " " + intent + ": " + service);
806 if (r != null) {
807 Intent.FilterComparison filter
808 = new Intent.FilterComparison(intent);
809 IntentBindRecord b = r.bindings.get(filter);
810 if (b != null && !b.received) {
811 b.binder = service;
812 b.requested = true;
813 b.received = true;
Dianne Hackborn390517b2013-05-30 15:03:32 -0700814 for (int conni=r.connections.size()-1; conni>=0; conni--) {
815 ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
816 for (int i=0; i<clist.size(); i++) {
817 ConnectionRecord c = clist.get(i);
818 if (!filter.equals(c.binding.intent.intent)) {
819 if (DEBUG_SERVICE) Slog.v(
820 TAG, "Not publishing to: " + c);
821 if (DEBUG_SERVICE) Slog.v(
822 TAG, "Bound intent: " + c.binding.intent.intent);
823 if (DEBUG_SERVICE) Slog.v(
824 TAG, "Published intent: " + intent);
825 continue;
826 }
827 if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
828 try {
829 c.conn.connected(r.name, service);
830 } catch (Exception e) {
831 Slog.w(TAG, "Failure sending service " + r.name +
832 " to connection " + c.conn.asBinder() +
833 " (in " + c.binding.client.processName + ")", e);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700834 }
835 }
836 }
837 }
838
Dianne Hackborn164371f2013-10-01 19:10:13 -0700839 serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700840 }
841 } finally {
842 Binder.restoreCallingIdentity(origId);
843 }
844 }
845
846 boolean unbindServiceLocked(IServiceConnection connection) {
847 IBinder binder = connection.asBinder();
848 if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
849 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
850 if (clist == null) {
851 Slog.w(TAG, "Unbind failed: could not find connection for "
852 + connection.asBinder());
853 return false;
854 }
855
856 final long origId = Binder.clearCallingIdentity();
857 try {
858 while (clist.size() > 0) {
859 ConnectionRecord r = clist.get(0);
860 removeConnectionLocked(r, null, null);
861
862 if (r.binding.service.app != null) {
863 // This could have made the service less important.
864 mAm.updateOomAdjLocked(r.binding.service.app);
865 }
866 }
867 } finally {
868 Binder.restoreCallingIdentity(origId);
869 }
870
871 return true;
872 }
873
874 void unbindFinishedLocked(ServiceRecord r, Intent intent, boolean doRebind) {
875 final long origId = Binder.clearCallingIdentity();
876 try {
877 if (r != null) {
878 Intent.FilterComparison filter
879 = new Intent.FilterComparison(intent);
880 IntentBindRecord b = r.bindings.get(filter);
881 if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
882 + " at " + b + ": apps="
883 + (b != null ? b.apps.size() : 0));
884
Dianne Hackborn164371f2013-10-01 19:10:13 -0700885 boolean inDestroying = mDestroyingServices.contains(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700886 if (b != null) {
Dianne Hackborn164371f2013-10-01 19:10:13 -0700887 if (b.apps.size() > 0 && !inDestroying) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700888 // Applications have already bound since the last
889 // unbind, so just rebind right here.
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700890 boolean inFg = false;
891 for (int i=b.apps.size()-1; i>=0; i--) {
892 ProcessRecord client = b.apps.valueAt(i).client;
893 if (client != null && client.setSchedGroup
894 != Process.THREAD_GROUP_BG_NONINTERACTIVE) {
895 inFg = true;
896 break;
897 }
898 }
899 requestServiceBindingLocked(r, b, inFg, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700900 } else {
901 // Note to tell the service the next time there is
902 // a new client.
903 b.doRebind = true;
904 }
905 }
906
Dianne Hackborn164371f2013-10-01 19:10:13 -0700907 serviceDoneExecutingLocked(r, inDestroying, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700908 }
909 } finally {
910 Binder.restoreCallingIdentity(origId);
911 }
912 }
913
914 private final ServiceRecord findServiceLocked(ComponentName name,
Dianne Hackborn41203752012-08-31 14:05:51 -0700915 IBinder token, int userId) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700916 ServiceRecord r = getServiceByName(name, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700917 return r == token ? r : null;
918 }
919
920 private final class ServiceLookupResult {
921 final ServiceRecord record;
922 final String permission;
923
924 ServiceLookupResult(ServiceRecord _record, String _permission) {
925 record = _record;
926 permission = _permission;
927 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700928 }
929
930 private class ServiceRestarter implements Runnable {
931 private ServiceRecord mService;
932
933 void setService(ServiceRecord service) {
934 mService = service;
935 }
936
937 public void run() {
938 synchronized(mAm) {
939 performServiceRestartLocked(mService);
940 }
941 }
942 }
943
944 private ServiceLookupResult retrieveServiceLocked(Intent service,
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -0700945 String resolvedType, int callingPid, int callingUid, int userId,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700946 boolean createIfNeeded, boolean callingFromFg) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700947 ServiceRecord r = null;
948 if (DEBUG_SERVICE) Slog.v(TAG, "retrieveServiceLocked: " + service
949 + " type=" + resolvedType + " callingUid=" + callingUid);
950
Dianne Hackborn139748f2012-09-24 11:36:57 -0700951 userId = mAm.handleIncomingUser(callingPid, callingUid, userId,
Dianne Hackborn5ac72a22012-08-29 18:32:08 -0700952 false, true, "service", null);
953
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700954 ServiceMap smap = getServiceMap(userId);
955 final ComponentName comp = service.getComponent();
956 if (comp != null) {
957 r = smap.mServicesByName.get(comp);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700958 }
959 if (r == null) {
960 Intent.FilterComparison filter = new Intent.FilterComparison(service);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700961 r = smap.mServicesByIntent.get(filter);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700962 }
963 if (r == null) {
964 try {
965 ResolveInfo rInfo =
966 AppGlobals.getPackageManager().resolveService(
967 service, resolvedType,
968 ActivityManagerService.STOCK_PM_FLAGS, userId);
969 ServiceInfo sInfo =
970 rInfo != null ? rInfo.serviceInfo : null;
971 if (sInfo == null) {
Amith Yamasani2b914652012-08-27 12:04:40 -0700972 Slog.w(TAG, "Unable to start service " + service + " U=" + userId +
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700973 ": not found");
974 return null;
975 }
976 ComponentName name = new ComponentName(
977 sInfo.applicationInfo.packageName, sInfo.name);
978 if (userId > 0) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -0700979 if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
980 sInfo.name, sInfo.flags)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700981 userId = 0;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700982 smap = getServiceMap(0);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700983 }
984 sInfo = new ServiceInfo(sInfo);
985 sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
986 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700987 r = smap.mServicesByName.get(name);
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -0700988 if (r == null && createIfNeeded) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700989 Intent.FilterComparison filter
990 = new Intent.FilterComparison(service.cloneFilter());
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700991 ServiceRestarter res = new ServiceRestarter();
992 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
993 BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics();
994 synchronized (stats) {
995 ss = stats.getServiceStatsLocked(
996 sInfo.applicationInfo.uid, sInfo.packageName,
997 sInfo.name);
998 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700999 r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001000 res.setService(r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001001 smap.mServicesByName.put(name, r);
1002 smap.mServicesByIntent.put(filter, r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001003
1004 // Make sure this component isn't in the pending list.
1005 int N = mPendingServices.size();
1006 for (int i=0; i<N; i++) {
1007 ServiceRecord pr = mPendingServices.get(i);
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001008 if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
1009 && pr.name.equals(name)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001010 mPendingServices.remove(i);
1011 i--;
1012 N--;
1013 }
1014 }
1015 }
1016 } catch (RemoteException ex) {
1017 // pm is in same process, this will never happen.
1018 }
1019 }
1020 if (r != null) {
1021 if (mAm.checkComponentPermission(r.permission,
1022 callingPid, callingUid, r.appInfo.uid, r.exported)
1023 != PackageManager.PERMISSION_GRANTED) {
1024 if (!r.exported) {
1025 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
1026 + " from pid=" + callingPid
1027 + ", uid=" + callingUid
1028 + " that is not exported from uid " + r.appInfo.uid);
1029 return new ServiceLookupResult(null, "not exported from uid "
1030 + r.appInfo.uid);
1031 }
1032 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
1033 + " from pid=" + callingPid
1034 + ", uid=" + callingUid
1035 + " requires " + r.permission);
1036 return new ServiceLookupResult(null, r.permission);
1037 }
Ben Gruverf5323fe2013-07-31 15:09:51 -07001038 if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
1039 resolvedType, r.appInfo)) {
Ben Gruverb6223792013-07-29 16:35:40 -07001040 return null;
1041 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001042 return new ServiceLookupResult(r, null);
1043 }
1044 return null;
1045 }
1046
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001047 private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001048 if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001049 + why + " of " + r + " in app " + r.app);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001050 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, ">>> EXECUTING "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001051 + why + " of " + r.shortName);
1052 long now = SystemClock.uptimeMillis();
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001053 if (r.executeNesting == 0) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001054 r.executeFg = fg;
Dianne Hackbornd2932242013-08-05 18:18:42 -07001055 ProcessStats.ServiceState stracker = r.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001056 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001057 stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001058 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001059 if (r.app != null) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001060 r.app.executingServices.add(r);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001061 r.app.execServicesFg |= fg;
Dianne Hackborn2be00932013-09-22 16:46:00 -07001062 if (r.app.executingServices.size() == 1) {
1063 scheduleServiceTimeoutLocked(r.app);
1064 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001065 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001066 } else if (r.app != null && fg && !r.app.execServicesFg) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001067 r.app.execServicesFg = true;
Dianne Hackborn2be00932013-09-22 16:46:00 -07001068 scheduleServiceTimeoutLocked(r.app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001069 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001070 r.executeFg |= fg;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001071 r.executeNesting++;
1072 r.executingStart = now;
1073 }
1074
1075 private final boolean requestServiceBindingLocked(ServiceRecord r,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001076 IntentBindRecord i, boolean execInFg, boolean rebind) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001077 if (r.app == null || r.app.thread == null) {
1078 // If service is not currently running, can't yet bind.
1079 return false;
1080 }
1081 if ((!i.requested || rebind) && i.apps.size() > 0) {
1082 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001083 bumpServiceExecutingLocked(r, execInFg, "bind");
Dianne Hackborna413dc02013-07-12 12:02:55 -07001084 r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
1085 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
1086 r.app.repProcState);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001087 if (!rebind) {
1088 i.requested = true;
1089 }
1090 i.hasBound = true;
1091 i.doRebind = false;
1092 } catch (RemoteException e) {
1093 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
1094 return false;
1095 }
1096 }
1097 return true;
1098 }
1099
1100 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
1101 boolean allowCancel) {
1102 boolean canceled = false;
1103
1104 final long now = SystemClock.uptimeMillis();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001105
1106 if ((r.serviceInfo.applicationInfo.flags
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001107 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
1108 long minDuration = SERVICE_RESTART_DURATION;
1109 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001110
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001111 // Any delivered but not yet finished starts should be put back
1112 // on the pending list.
1113 final int N = r.deliveredStarts.size();
1114 if (N > 0) {
1115 for (int i=N-1; i>=0; i--) {
1116 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
1117 si.removeUriPermissionsLocked();
1118 if (si.intent == null) {
1119 // We'll generate this again if needed.
1120 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
1121 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
1122 r.pendingStarts.add(0, si);
1123 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
1124 dur *= 2;
1125 if (minDuration < dur) minDuration = dur;
1126 if (resetTime < dur) resetTime = dur;
1127 } else {
1128 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
1129 + r.name);
1130 canceled = true;
1131 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001132 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001133 r.deliveredStarts.clear();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001134 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001135
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001136 r.totalRestartCount++;
1137 if (r.restartDelay == 0) {
1138 r.restartCount++;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001139 r.restartDelay = minDuration;
1140 } else {
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001141 // If it has been a "reasonably long time" since the service
1142 // was started, then reset our restart duration back to
1143 // the beginning, so we don't infinitely increase the duration
1144 // on a service that just occasionally gets killed (which is
1145 // a normal case, due to process being killed to reclaim memory).
1146 if (now > (r.restartTime+resetTime)) {
1147 r.restartCount = 1;
1148 r.restartDelay = minDuration;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001149 } else {
Dianne Hackborn7b492722013-11-01 09:58:45 -07001150 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
1151 if (r.restartDelay < minDuration) {
1152 r.restartDelay = minDuration;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001153 }
1154 }
1155 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001156
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001157 r.nextRestartTime = now + r.restartDelay;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001158
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001159 // Make sure that we don't end up restarting a bunch of services
1160 // all at the same time.
1161 boolean repeat;
1162 do {
1163 repeat = false;
1164 for (int i=mRestartingServices.size()-1; i>=0; i--) {
1165 ServiceRecord r2 = mRestartingServices.get(i);
1166 if (r2 != r && r.nextRestartTime
1167 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
1168 && r.nextRestartTime
1169 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
1170 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
1171 r.restartDelay = r.nextRestartTime - now;
1172 repeat = true;
1173 break;
1174 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001175 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001176 } while (repeat);
1177
1178 } else {
Dianne Hackborn7b492722013-11-01 09:58:45 -07001179 // Persistent processes are immediately restarted, so there is no
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001180 // reason to hold of on restarting their services.
1181 r.totalRestartCount++;
1182 r.restartCount = 0;
1183 r.restartDelay = 0;
1184 r.nextRestartTime = now;
1185 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001186
1187 if (!mRestartingServices.contains(r)) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001188 r.createdFromFg = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001189 mRestartingServices.add(r);
1190 }
1191
1192 r.cancelNotification();
1193
1194 mAm.mHandler.removeCallbacks(r.restarter);
1195 mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime);
1196 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
1197 Slog.w(TAG, "Scheduling restart of crashed service "
1198 + r.shortName + " in " + r.restartDelay + "ms");
1199 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001200 r.userId, r.shortName, r.restartDelay);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001201
1202 return canceled;
1203 }
1204
1205 final void performServiceRestartLocked(ServiceRecord r) {
1206 if (!mRestartingServices.contains(r)) {
1207 return;
1208 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001209 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001210 }
1211
Dianne Hackborn7b492722013-11-01 09:58:45 -07001212 private final boolean unscheduleServiceRestartLocked(ServiceRecord r, int callingUid) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001213 if (r.restartDelay == 0) {
1214 return false;
1215 }
Dianne Hackborn7b492722013-11-01 09:58:45 -07001216 // Remove from the restarting list; if the service is currently on the
1217 // restarting list, or the call is coming from another app, then this
1218 // service has become of much more interest so we reset the restart interval.
1219 boolean removed = mRestartingServices.remove(r);
1220 if (removed || callingUid != r.appInfo.uid) {
1221 r.resetRestartCounter();
1222 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001223 mAm.mHandler.removeCallbacks(r.restarter);
1224 return true;
1225 }
1226
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001227 private final String bringUpServiceLocked(ServiceRecord r,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001228 int intentFlags, boolean execInFg, boolean whileRestarting) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001229 //Slog.i(TAG, "Bring up service:");
1230 //r.dump(" ");
1231
1232 if (r.app != null && r.app.thread != null) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001233 sendServiceArgsLocked(r, execInFg, false);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001234 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001235 }
1236
1237 if (!whileRestarting && r.restartDelay > 0) {
1238 // If waiting for a restart, then do nothing.
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001239 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001240 }
1241
1242 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
1243
1244 // We are now bringing the service up, so no longer in the
1245 // restarting state.
1246 mRestartingServices.remove(r);
1247
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001248 // Make sure this service is no longer considered delayed, we are starting it now.
1249 if (r.delayed) {
1250 if (DEBUG_DELAYED_STATS) Slog.v(TAG, "REM FR DELAY LIST (bring up): " + r);
1251 getServiceMap(r.userId).mDelayedStartList.remove(r);
1252 r.delayed = false;
1253 }
1254
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001255 // Make sure that the user who owns this service is started. If not,
1256 // we don't want to allow it to run.
1257 if (mAm.mStartedUsers.get(r.userId) == null) {
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001258 String msg = "Unable to launch app "
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001259 + r.appInfo.packageName + "/"
1260 + r.appInfo.uid + " for service "
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001261 + r.intent.getIntent() + ": user " + r.userId + " is stopped";
1262 Slog.w(TAG, msg);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001263 bringDownServiceLocked(r);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001264 return msg;
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001265 }
1266
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001267 // Service is now being launched, its package can't be stopped.
1268 try {
1269 AppGlobals.getPackageManager().setPackageStoppedState(
1270 r.packageName, false, r.userId);
1271 } catch (RemoteException e) {
1272 } catch (IllegalArgumentException e) {
1273 Slog.w(TAG, "Failed trying to unstop package "
1274 + r.packageName + ": " + e);
1275 }
1276
1277 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
1278 final String procName = r.processName;
1279 ProcessRecord app;
1280
1281 if (!isolated) {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001282 app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
1283 if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
1284 + " app=" + app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001285 if (app != null && app.thread != null) {
1286 try {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001287 app.addPackage(r.appInfo.packageName, mAm.mProcessStats);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001288 realStartServiceLocked(r, app, execInFg);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001289 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001290 } catch (RemoteException e) {
1291 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
1292 }
1293
1294 // If a dead object exception was thrown -- fall through to
1295 // restart the application.
1296 }
1297 } else {
1298 // If this service runs in an isolated process, then each time
1299 // we call startProcessLocked() we will get a new isolated
1300 // process, starting another process if we are currently waiting
1301 // for a previous process to come up. To deal with this, we store
1302 // in the service any current isolated process it is running in or
1303 // waiting to have come up.
1304 app = r.isolatedProc;
1305 }
1306
1307 // Not running -- get it started, and enqueue this service record
1308 // to be executed when the app comes up.
1309 if (app == null) {
1310 if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001311 "service", r.name, false, isolated, false)) == null) {
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001312 String msg = "Unable to launch app "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001313 + r.appInfo.packageName + "/"
1314 + r.appInfo.uid + " for service "
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001315 + r.intent.getIntent() + ": process is bad";
1316 Slog.w(TAG, msg);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001317 bringDownServiceLocked(r);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001318 return msg;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001319 }
1320 if (isolated) {
1321 r.isolatedProc = app;
1322 }
1323 }
1324
1325 if (!mPendingServices.contains(r)) {
1326 mPendingServices.add(r);
1327 }
1328
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001329 if (r.delayedStop) {
1330 // Oh and hey we've already been asked to stop!
1331 r.delayedStop = false;
1332 if (r.startRequested) {
1333 if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Applying delayed stop (in bring up): " + r);
1334 stopServiceLocked(r);
1335 }
1336 }
1337
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001338 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001339 }
1340
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001341 private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07001342 for (int i=r.bindings.size()-1; i>=0; i--) {
1343 IntentBindRecord ibr = r.bindings.valueAt(i);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001344 if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001345 break;
1346 }
1347 }
1348 }
1349
1350 private final void realStartServiceLocked(ServiceRecord r,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001351 ProcessRecord app, boolean execInFg) throws RemoteException {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001352 if (app.thread == null) {
1353 throw new RemoteException();
1354 }
1355 if (DEBUG_MU)
1356 Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
1357 + ", ProcessRecord.uid = " + app.uid);
1358 r.app = app;
1359 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
1360
1361 app.services.add(r);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001362 bumpServiceExecutingLocked(r, execInFg, "create");
Dianne Hackborndb926082013-10-31 16:32:44 -07001363 mAm.updateLruProcessLocked(app, false, null);
1364 mAm.updateOomAdjLocked();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001365
1366 boolean created = false;
1367 try {
Dianne Hackborncf1171642013-07-12 17:26:02 -07001368 String nameTerm;
1369 int lastPeriod = r.shortName.lastIndexOf('.');
1370 nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
Jeff Sharkey9d6d8902012-11-09 17:32:43 -08001371 EventLogTags.writeAmCreateService(
Dianne Hackborncf1171642013-07-12 17:26:02 -07001372 r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001373 synchronized (r.stats.getBatteryStats()) {
1374 r.stats.startLaunchedLocked();
1375 }
1376 mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborna413dc02013-07-12 12:02:55 -07001377 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001378 app.thread.scheduleCreateService(r, r.serviceInfo,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001379 mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
1380 app.repProcState);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001381 r.postNotification();
1382 created = true;
1383 } finally {
1384 if (!created) {
1385 app.services.remove(r);
1386 scheduleServiceRestartLocked(r, false);
1387 }
1388 }
1389
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001390 requestServiceBindingsLocked(r, execInFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001391
1392 // If the service is in the started state, and there are no
1393 // pending arguments, then fake up one so its onStartCommand() will
1394 // be called.
1395 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
1396 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
1397 null, null));
1398 }
1399
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001400 sendServiceArgsLocked(r, execInFg, true);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001401
1402 if (r.delayed) {
1403 if (DEBUG_DELAYED_STATS) Slog.v(TAG, "REM FR DELAY LIST (new proc): " + r);
1404 getServiceMap(r.userId).mDelayedStartList.remove(r);
1405 r.delayed = false;
1406 }
1407
1408 if (r.delayedStop) {
1409 // Oh and hey we've already been asked to stop!
1410 r.delayedStop = false;
1411 if (r.startRequested) {
1412 if (DEBUG_DELAYED_STATS) Slog.v(TAG, "Applying delayed stop (from start): " + r);
1413 stopServiceLocked(r);
1414 }
1415 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001416 }
1417
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001418 private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001419 boolean oomAdjusted) {
1420 final int N = r.pendingStarts.size();
1421 if (N == 0) {
1422 return;
1423 }
1424
1425 while (r.pendingStarts.size() > 0) {
1426 try {
1427 ServiceRecord.StartItem si = r.pendingStarts.remove(0);
1428 if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
1429 + r + " " + r.intent + " args=" + si.intent);
1430 if (si.intent == null && N > 1) {
1431 // If somehow we got a dummy null intent in the middle,
1432 // then skip it. DO NOT skip a null intent when it is
1433 // the only one in the list -- this is to support the
1434 // onStartCommand(null) case.
1435 continue;
1436 }
1437 si.deliveredTime = SystemClock.uptimeMillis();
1438 r.deliveredStarts.add(si);
1439 si.deliveryCount++;
1440 if (si.neededGrants != null) {
1441 mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
1442 si.getUriPermissionsLocked());
1443 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001444 bumpServiceExecutingLocked(r, execInFg, "start");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001445 if (!oomAdjusted) {
1446 oomAdjusted = true;
1447 mAm.updateOomAdjLocked(r.app);
1448 }
1449 int flags = 0;
1450 if (si.deliveryCount > 1) {
1451 flags |= Service.START_FLAG_RETRY;
1452 }
1453 if (si.doneExecutingCount > 0) {
1454 flags |= Service.START_FLAG_REDELIVERY;
1455 }
1456 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
1457 } catch (RemoteException e) {
1458 // Remote process gone... we'll let the normal cleanup take
1459 // care of this.
1460 if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
1461 break;
1462 } catch (Exception e) {
1463 Slog.w(TAG, "Unexpected exception", e);
1464 break;
1465 }
1466 }
1467 }
1468
Dianne Hackborn164371f2013-10-01 19:10:13 -07001469 private final boolean isServiceNeeded(ServiceRecord r, boolean knowConn, boolean hasConn) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001470 // Are we still explicitly being asked to run?
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001471 if (r.startRequested) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001472 return true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001473 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001474
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001475 // Is someone still bound to us keepign us running?
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001476 if (!knowConn) {
1477 hasConn = r.hasAutoCreateConnections();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001478 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001479 if (hasConn) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001480 return true;
1481 }
1482
1483 return false;
1484 }
1485
1486 private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
1487 boolean hasConn) {
1488 //Slog.i(TAG, "Bring down service:");
1489 //r.dump(" ");
1490
1491 if (isServiceNeeded(r, knowConn, hasConn)) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001492 return;
1493 }
1494
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001495 // Are we in the process of launching?
1496 if (mPendingServices.contains(r)) {
1497 return;
1498 }
1499
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001500 bringDownServiceLocked(r);
1501 }
1502
1503 private final void bringDownServiceLocked(ServiceRecord r) {
1504 //Slog.i(TAG, "Bring down service:");
1505 //r.dump(" ");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001506
Dianne Hackborn390517b2013-05-30 15:03:32 -07001507 // Report to all of the connections that the service is no longer
1508 // available.
1509 for (int conni=r.connections.size()-1; conni>=0; conni--) {
1510 ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
1511 for (int i=0; i<c.size(); i++) {
1512 ConnectionRecord cr = c.get(i);
1513 // There is still a connection to the service that is
1514 // being brought down. Mark it as dead.
1515 cr.serviceDead = true;
1516 try {
1517 cr.conn.connected(r.name, null);
1518 } catch (Exception e) {
1519 Slog.w(TAG, "Failure disconnecting service " + r.name +
1520 " to connection " + c.get(i).conn.asBinder() +
1521 " (in " + c.get(i).binding.client.processName + ")", e);
1522 }
1523 }
1524 }
1525
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001526 // Tell the service that it has been unbound.
Dianne Hackborn390517b2013-05-30 15:03:32 -07001527 if (r.app != null && r.app.thread != null) {
1528 for (int i=r.bindings.size()-1; i>=0; i--) {
1529 IntentBindRecord ibr = r.bindings.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001530 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
1531 + ": hasBound=" + ibr.hasBound);
Dianne Hackborn390517b2013-05-30 15:03:32 -07001532 if (ibr.hasBound) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001533 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001534 bumpServiceExecutingLocked(r, false, "bring down unbind");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001535 mAm.updateOomAdjLocked(r.app);
1536 ibr.hasBound = false;
1537 r.app.thread.scheduleUnbindService(r,
1538 ibr.intent.getIntent());
1539 } catch (Exception e) {
1540 Slog.w(TAG, "Exception when unbinding service "
1541 + r.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001542 serviceProcessGoneLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001543 }
1544 }
1545 }
1546 }
1547
1548 if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
Jeff Sharkey9d6d8902012-11-09 17:32:43 -08001549 EventLogTags.writeAmDestroyService(
1550 r.userId, System.identityHashCode(r), (r.app != null) ? r.app.pid : -1);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001551
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001552 final ServiceMap smap = getServiceMap(r.userId);
1553 smap.mServicesByName.remove(r.name);
1554 smap.mServicesByIntent.remove(r.intent);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001555 r.totalRestartCount = 0;
Dianne Hackborn7b492722013-11-01 09:58:45 -07001556 unscheduleServiceRestartLocked(r, 0);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001557
1558 // Also make sure it is not on the pending list.
1559 int N = mPendingServices.size();
1560 for (int i=0; i<N; i++) {
1561 if (mPendingServices.get(i) == r) {
1562 mPendingServices.remove(i);
1563 if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
1564 i--;
1565 N--;
1566 }
1567 }
1568
1569 r.cancelNotification();
1570 r.isForeground = false;
1571 r.foregroundId = 0;
1572 r.foregroundNoti = null;
1573
1574 // Clear start entries.
1575 r.clearDeliveredStartsLocked();
1576 r.pendingStarts.clear();
1577
1578 if (r.app != null) {
1579 synchronized (r.stats.getBatteryStats()) {
1580 r.stats.stopLaunchedLocked();
1581 }
1582 r.app.services.remove(r);
1583 if (r.app.thread != null) {
1584 try {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001585 bumpServiceExecutingLocked(r, false, "destroy");
1586 mDestroyingServices.add(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001587 mAm.updateOomAdjLocked(r.app);
1588 r.app.thread.scheduleStopService(r);
1589 } catch (Exception e) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001590 Slog.w(TAG, "Exception when destroying service "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001591 + r.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001592 serviceProcessGoneLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001593 }
1594 updateServiceForegroundLocked(r.app, false);
1595 } else {
1596 if (DEBUG_SERVICE) Slog.v(
1597 TAG, "Removed service that has no process: " + r);
1598 }
1599 } else {
1600 if (DEBUG_SERVICE) Slog.v(
1601 TAG, "Removed service that is not running: " + r);
1602 }
1603
1604 if (r.bindings.size() > 0) {
1605 r.bindings.clear();
1606 }
1607
1608 if (r.restarter instanceof ServiceRestarter) {
1609 ((ServiceRestarter)r.restarter).setService(null);
1610 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001611
Dianne Hackbornd2932242013-08-05 18:18:42 -07001612 int memFactor = mAm.mProcessStats.getMemFactorLocked();
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001613 long now = SystemClock.uptimeMillis();
1614 if (r.tracker != null) {
1615 r.tracker.setStarted(false, memFactor, now);
1616 r.tracker.setBound(false, memFactor, now);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001617 if (r.executeNesting == 0) {
Dianne Hackborn878deb32013-10-14 16:55:09 -07001618 r.tracker.clearCurrentOwner(r, false);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001619 r.tracker = null;
1620 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001621 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001622
1623 smap.ensureNotStartingBackground(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001624 }
1625
1626 void removeConnectionLocked(
1627 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
1628 IBinder binder = c.conn.asBinder();
1629 AppBindRecord b = c.binding;
1630 ServiceRecord s = b.service;
1631 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
1632 if (clist != null) {
1633 clist.remove(c);
1634 if (clist.size() == 0) {
1635 s.connections.remove(binder);
1636 }
1637 }
1638 b.connections.remove(c);
1639 if (c.activity != null && c.activity != skipAct) {
1640 if (c.activity.connections != null) {
1641 c.activity.connections.remove(c);
1642 }
1643 }
1644 if (b.client != skipApp) {
1645 b.client.connections.remove(c);
1646 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
1647 b.client.updateHasAboveClientLocked();
1648 }
Dianne Hackborndb926082013-10-31 16:32:44 -07001649 if (s.app != null) {
1650 updateServiceClientActivitiesLocked(s.app, c);
1651 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001652 }
1653 clist = mServiceConnections.get(binder);
1654 if (clist != null) {
1655 clist.remove(c);
1656 if (clist.size() == 0) {
1657 mServiceConnections.remove(binder);
1658 }
1659 }
1660
1661 if (b.connections.size() == 0) {
1662 b.intent.apps.remove(b.client);
1663 }
1664
1665 if (!c.serviceDead) {
1666 if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
1667 + ": shouldUnbind=" + b.intent.hasBound);
1668 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
1669 && b.intent.hasBound) {
1670 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001671 bumpServiceExecutingLocked(s, false, "unbind");
Dianne Hackborndb926082013-10-31 16:32:44 -07001672 if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0
1673 && s.app.setProcState <= ActivityManager.PROCESS_STATE_RECEIVER) {
1674 // If this service's process is not already in the cached list,
1675 // then update it in the LRU list here because this may be causing
1676 // it to go down there and we want it to start out near the top.
1677 mAm.updateLruProcessLocked(s.app, false, null);
1678 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001679 mAm.updateOomAdjLocked(s.app);
1680 b.intent.hasBound = false;
1681 // Assume the client doesn't want to know about a rebind;
1682 // we will deal with that later if it asks for one.
1683 b.intent.doRebind = false;
1684 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
1685 } catch (Exception e) {
1686 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001687 serviceProcessGoneLocked(s);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001688 }
1689 }
1690
1691 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001692 boolean hasAutoCreate = s.hasAutoCreateConnections();
1693 if (!hasAutoCreate) {
1694 if (s.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001695 s.tracker.setBound(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001696 SystemClock.uptimeMillis());
1697 }
1698 }
1699 bringDownServiceIfNeededLocked(s, true, hasAutoCreate);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001700 }
1701 }
1702 }
1703
1704 void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001705 boolean inDestroying = mDestroyingServices.contains(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001706 if (r != null) {
1707 if (type == 1) {
1708 // This is a call from a service start... take care of
1709 // book-keeping.
1710 r.callStart = true;
1711 switch (res) {
1712 case Service.START_STICKY_COMPATIBILITY:
1713 case Service.START_STICKY: {
1714 // We are done with the associated start arguments.
1715 r.findDeliveredStart(startId, true);
1716 // Don't stop if killed.
1717 r.stopIfKilled = false;
1718 break;
1719 }
1720 case Service.START_NOT_STICKY: {
1721 // We are done with the associated start arguments.
1722 r.findDeliveredStart(startId, true);
1723 if (r.getLastStartId() == startId) {
1724 // There is no more work, and this service
1725 // doesn't want to hang around if killed.
1726 r.stopIfKilled = true;
1727 }
1728 break;
1729 }
1730 case Service.START_REDELIVER_INTENT: {
1731 // We'll keep this item until they explicitly
1732 // call stop for it, but keep track of the fact
1733 // that it was delivered.
1734 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
1735 if (si != null) {
1736 si.deliveryCount = 0;
1737 si.doneExecutingCount++;
1738 // Don't stop if killed.
1739 r.stopIfKilled = true;
1740 }
1741 break;
1742 }
1743 case Service.START_TASK_REMOVED_COMPLETE: {
1744 // Special processing for onTaskRemoved(). Don't
1745 // impact normal onStartCommand() processing.
1746 r.findDeliveredStart(startId, true);
1747 break;
1748 }
1749 default:
1750 throw new IllegalArgumentException(
1751 "Unknown service start result: " + res);
1752 }
1753 if (res == Service.START_STICKY_COMPATIBILITY) {
1754 r.callStart = false;
1755 }
1756 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001757 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn164371f2013-10-01 19:10:13 -07001758 serviceDoneExecutingLocked(r, inDestroying, inDestroying);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001759 Binder.restoreCallingIdentity(origId);
1760 } else {
1761 Slog.w(TAG, "Done executing unknown service from pid "
1762 + Binder.getCallingPid());
1763 }
1764 }
1765
Dianne Hackborn878deb32013-10-14 16:55:09 -07001766 private void serviceProcessGoneLocked(ServiceRecord r) {
1767 if (r.tracker != null) {
1768 int memFactor = mAm.mProcessStats.getMemFactorLocked();
1769 long now = SystemClock.uptimeMillis();
1770 r.tracker.setExecuting(false, memFactor, now);
1771 r.tracker.setBound(false, memFactor, now);
1772 }
1773 serviceDoneExecutingLocked(r, true, true);
1774 }
1775
Dianne Hackborn164371f2013-10-01 19:10:13 -07001776 private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
1777 boolean finishing) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001778 if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
1779 + ": nesting=" + r.executeNesting
Dianne Hackborn164371f2013-10-01 19:10:13 -07001780 + ", inDestroying=" + inDestroying + ", app=" + r.app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001781 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
1782 r.executeNesting--;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001783 if (r.executeNesting <= 0) {
1784 if (r.app != null) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001785 if (DEBUG_SERVICE) Slog.v(TAG,
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001786 "Nesting at 0 of " + r.shortName);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001787 r.app.execServicesFg = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001788 r.app.executingServices.remove(r);
1789 if (r.app.executingServices.size() == 0) {
1790 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
1791 "No more executingServices of " + r.shortName);
1792 mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001793 } else if (r.executeFg) {
1794 // Need to re-evaluate whether the app still needs to be in the foreground.
1795 for (int i=r.app.executingServices.size()-1; i>=0; i--) {
1796 if (r.app.executingServices.valueAt(i).executeFg) {
1797 r.app.execServicesFg = true;
1798 break;
1799 }
1800 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001801 }
Dianne Hackborn164371f2013-10-01 19:10:13 -07001802 if (inDestroying) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001803 if (DEBUG_SERVICE) Slog.v(TAG,
Dianne Hackborn164371f2013-10-01 19:10:13 -07001804 "doneExecuting remove destroying " + r);
1805 mDestroyingServices.remove(r);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001806 r.bindings.clear();
1807 }
1808 mAm.updateOomAdjLocked(r.app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001809 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001810 r.executeFg = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001811 if (r.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001812 r.tracker.setExecuting(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001813 SystemClock.uptimeMillis());
Dianne Hackborn164371f2013-10-01 19:10:13 -07001814 if (finishing) {
Dianne Hackborn878deb32013-10-14 16:55:09 -07001815 r.tracker.clearCurrentOwner(r, false);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001816 r.tracker = null;
1817 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001818 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001819 }
1820 }
1821
1822 boolean attachApplicationLocked(ProcessRecord proc, String processName) throws Exception {
1823 boolean didSomething = false;
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001824 // Collect any services that are waiting for this process to come up.
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001825 if (mPendingServices.size() > 0) {
1826 ServiceRecord sr = null;
1827 try {
1828 for (int i=0; i<mPendingServices.size(); i++) {
1829 sr = mPendingServices.get(i);
1830 if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
1831 || !processName.equals(sr.processName))) {
1832 continue;
1833 }
1834
1835 mPendingServices.remove(i);
1836 i--;
Dianne Hackbornd2932242013-08-05 18:18:42 -07001837 proc.addPackage(sr.appInfo.packageName, mAm.mProcessStats);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001838 realStartServiceLocked(sr, proc, sr.createdFromFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001839 didSomething = true;
1840 }
1841 } catch (Exception e) {
1842 Slog.w(TAG, "Exception in new application when starting service "
1843 + sr.shortName, e);
1844 throw e;
1845 }
1846 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001847 // Also, if there are any services that are waiting to restart and
1848 // would run in this process, now is a good time to start them. It would
1849 // be weird to bring up the process but arbitrarily not let the services
1850 // run at this point just because their restart time hasn't come up.
1851 if (mRestartingServices.size() > 0) {
1852 ServiceRecord sr = null;
1853 for (int i=0; i<mRestartingServices.size(); i++) {
1854 sr = mRestartingServices.get(i);
1855 if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
1856 || !processName.equals(sr.processName))) {
1857 continue;
1858 }
1859 mAm.mHandler.removeCallbacks(sr.restarter);
1860 mAm.mHandler.post(sr.restarter);
1861 }
1862 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001863 return didSomething;
1864 }
1865
1866 void processStartTimedOutLocked(ProcessRecord proc) {
1867 for (int i=0; i<mPendingServices.size(); i++) {
1868 ServiceRecord sr = mPendingServices.get(i);
1869 if ((proc.uid == sr.appInfo.uid
1870 && proc.processName.equals(sr.processName))
1871 || sr.isolatedProc == proc) {
1872 Slog.w(TAG, "Forcing bringing down service: " + sr);
1873 sr.isolatedProc = null;
1874 mPendingServices.remove(i);
1875 i--;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001876 bringDownServiceLocked(sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001877 }
1878 }
1879 }
1880
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001881 private boolean collectForceStopServicesLocked(String name, int userId,
1882 boolean evenPersistent, boolean doit,
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001883 ArrayMap<ComponentName, ServiceRecord> services,
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001884 ArrayList<ServiceRecord> result) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001885 boolean didSomething = false;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001886 for (int i=0; i<services.size(); i++) {
1887 ServiceRecord service = services.valueAt(i);
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001888 if ((name == null || service.packageName.equals(name))
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001889 && (service.app == null || evenPersistent || !service.app.persistent)) {
1890 if (!doit) {
1891 return true;
1892 }
1893 didSomething = true;
1894 Slog.i(TAG, " Force stopping service " + service);
1895 if (service.app != null) {
1896 service.app.removed = true;
1897 }
1898 service.app = null;
1899 service.isolatedProc = null;
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001900 result.add(service);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001901 }
1902 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001903 return didSomething;
1904 }
1905
1906 boolean forceStopLocked(String name, int userId, boolean evenPersistent, boolean doit) {
1907 boolean didSomething = false;
1908 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
1909 if (userId == UserHandle.USER_ALL) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001910 for (int i=0; i<mServiceMap.size(); i++) {
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001911 didSomething |= collectForceStopServicesLocked(name, userId, evenPersistent,
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001912 doit, mServiceMap.valueAt(i).mServicesByName, services);
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001913 if (!doit && didSomething) {
1914 return true;
1915 }
1916 }
1917 } else {
Amith Yamasani540b6592013-10-01 13:02:52 -07001918 ServiceMap smap = mServiceMap.get(userId);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001919 if (smap != null) {
1920 ArrayMap<ComponentName, ServiceRecord> items = smap.mServicesByName;
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07001921 didSomething = collectForceStopServicesLocked(name, userId, evenPersistent,
1922 doit, items, services);
1923 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07001924 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001925
1926 int N = services.size();
1927 for (int i=0; i<N; i++) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001928 bringDownServiceLocked(services.get(i));
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001929 }
1930 return didSomething;
1931 }
1932
1933 void cleanUpRemovedTaskLocked(TaskRecord tr, ComponentName component, Intent baseIntent) {
1934 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001935 ArrayMap<ComponentName, ServiceRecord> alls = getServices(tr.userId);
1936 for (int i=0; i<alls.size(); i++) {
1937 ServiceRecord sr = alls.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001938 if (sr.packageName.equals(component.getPackageName())) {
1939 services.add(sr);
1940 }
1941 }
1942
1943 // Take care of any running services associated with the app.
1944 for (int i=0; i<services.size(); i++) {
1945 ServiceRecord sr = services.get(i);
1946 if (sr.startRequested) {
1947 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
1948 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
1949 stopServiceLocked(sr);
1950 } else {
1951 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
1952 sr.makeNextStartId(), baseIntent, null));
1953 if (sr.app != null && sr.app.thread != null) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001954 // We always run in the foreground, since this is called as
1955 // part of the "remove task" UI operation.
1956 sendServiceArgsLocked(sr, true, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001957 }
1958 }
1959 }
1960 }
1961 }
1962
1963 final void killServicesLocked(ProcessRecord app,
1964 boolean allowRestart) {
1965 // Report disconnected services.
1966 if (false) {
1967 // XXX we are letting the client link to the service for
1968 // death notifications.
1969 if (app.services.size() > 0) {
1970 Iterator<ServiceRecord> it = app.services.iterator();
1971 while (it.hasNext()) {
1972 ServiceRecord r = it.next();
Dianne Hackborn390517b2013-05-30 15:03:32 -07001973 for (int conni=r.connections.size()-1; conni>=0; conni--) {
1974 ArrayList<ConnectionRecord> cl = r.connections.valueAt(conni);
1975 for (int i=0; i<cl.size(); i++) {
1976 ConnectionRecord c = cl.get(i);
1977 if (c.binding.client != app) {
1978 try {
1979 //c.conn.connected(r.className, null);
1980 } catch (Exception e) {
1981 // todo: this should be asynchronous!
1982 Slog.w(TAG, "Exception thrown disconnected servce "
1983 + r.shortName
1984 + " from app " + app.processName, e);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001985 }
1986 }
1987 }
1988 }
1989 }
1990 }
1991 }
1992
1993 // Clean up any connections this application has to other services.
Dianne Hackbornc8230512013-07-13 21:32:12 -07001994 for (int i=app.connections.size()-1; i>=0; i--) {
1995 ConnectionRecord r = app.connections.valueAt(i);
1996 removeConnectionLocked(r, app, null);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001997 }
1998 app.connections.clear();
1999
Dianne Hackbornc8230512013-07-13 21:32:12 -07002000 for (int i=app.services.size()-1; i>=0; i--) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002001 // Any services running in the application need to be placed
2002 // back in the pending list.
Dianne Hackbornc8230512013-07-13 21:32:12 -07002003 ServiceRecord sr = app.services.valueAt(i);
2004 synchronized (sr.stats.getBatteryStats()) {
2005 sr.stats.stopLaunchedLocked();
2006 }
2007 sr.app = null;
2008 sr.isolatedProc = null;
2009 sr.executeNesting = 0;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002010 sr.forceClearTracker();
2011 if (mDestroyingServices.remove(sr)) {
2012 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove destroying " + sr);
Dianne Hackbornc8230512013-07-13 21:32:12 -07002013 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002014
Dianne Hackbornc8230512013-07-13 21:32:12 -07002015 final int numClients = sr.bindings.size();
2016 for (int bindingi=numClients-1; bindingi>=0; bindingi--) {
2017 IntentBindRecord b = sr.bindings.valueAt(bindingi);
2018 if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
2019 + ": shouldUnbind=" + b.hasBound);
2020 b.binder = null;
2021 b.requested = b.received = b.hasBound = false;
2022 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002023
Dianne Hackbornc8230512013-07-13 21:32:12 -07002024 if (sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
2025 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
2026 Slog.w(TAG, "Service crashed " + sr.crashCount
2027 + " times, stopping: " + sr);
2028 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
2029 sr.userId, sr.crashCount, sr.shortName, app.pid);
2030 bringDownServiceLocked(sr);
2031 } else if (!allowRestart) {
2032 bringDownServiceLocked(sr);
2033 } else {
2034 boolean canceled = scheduleServiceRestartLocked(sr, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002035
Dianne Hackbornc8230512013-07-13 21:32:12 -07002036 // Should the service remain running? Note that in the
2037 // extreme case of so many attempts to deliver a command
2038 // that it failed we also will stop it here.
2039 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
2040 if (sr.pendingStarts.size() == 0) {
2041 sr.startRequested = false;
2042 if (sr.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07002043 sr.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackbornc8230512013-07-13 21:32:12 -07002044 SystemClock.uptimeMillis());
2045 }
2046 if (!sr.hasAutoCreateConnections()) {
2047 // Whoops, no reason to restart!
2048 bringDownServiceLocked(sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002049 }
2050 }
2051 }
2052 }
Dianne Hackbornc8230512013-07-13 21:32:12 -07002053 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002054
Dianne Hackbornc8230512013-07-13 21:32:12 -07002055 if (!allowRestart) {
2056 app.services.clear();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002057 }
2058
2059 // Make sure we have no more records on the stopping list.
Dianne Hackborn164371f2013-10-01 19:10:13 -07002060 int i = mDestroyingServices.size();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002061 while (i > 0) {
2062 i--;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002063 ServiceRecord sr = mDestroyingServices.get(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002064 if (sr.app == app) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07002065 sr.forceClearTracker();
2066 mDestroyingServices.remove(i);
2067 if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove destroying " + sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002068 }
2069 }
2070
2071 app.executingServices.clear();
2072 }
2073
2074 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
2075 ActivityManager.RunningServiceInfo info =
2076 new ActivityManager.RunningServiceInfo();
2077 info.service = r.name;
2078 if (r.app != null) {
2079 info.pid = r.app.pid;
2080 }
2081 info.uid = r.appInfo.uid;
2082 info.process = r.processName;
2083 info.foreground = r.isForeground;
2084 info.activeSince = r.createTime;
2085 info.started = r.startRequested;
2086 info.clientCount = r.connections.size();
2087 info.crashCount = r.crashCount;
2088 info.lastActivityTime = r.lastActivity;
2089 if (r.isForeground) {
2090 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
2091 }
2092 if (r.startRequested) {
2093 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
2094 }
2095 if (r.app != null && r.app.pid == ActivityManagerService.MY_PID) {
2096 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
2097 }
2098 if (r.app != null && r.app.persistent) {
2099 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
2100 }
2101
Dianne Hackborn390517b2013-05-30 15:03:32 -07002102 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2103 ArrayList<ConnectionRecord> connl = r.connections.valueAt(conni);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002104 for (int i=0; i<connl.size(); i++) {
2105 ConnectionRecord conn = connl.get(i);
2106 if (conn.clientLabel != 0) {
2107 info.clientPackage = conn.binding.client.info.packageName;
2108 info.clientLabel = conn.clientLabel;
2109 return info;
2110 }
2111 }
2112 }
2113 return info;
2114 }
2115
2116 List<ActivityManager.RunningServiceInfo> getRunningServiceInfoLocked(int maxNum,
2117 int flags) {
2118 ArrayList<ActivityManager.RunningServiceInfo> res
2119 = new ArrayList<ActivityManager.RunningServiceInfo>();
2120
Dianne Hackborn0c380492012-08-20 17:23:30 -07002121 final int uid = Binder.getCallingUid();
2122 final long ident = Binder.clearCallingIdentity();
2123 try {
2124 if (ActivityManager.checkUidPermission(
2125 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2126 uid) == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn1676c852012-09-10 14:52:30 -07002127 int[] users = mAm.getUsersLocked();
2128 for (int ui=0; ui<users.length && res.size() < maxNum; ui++) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002129 ArrayMap<ComponentName, ServiceRecord> alls = getServices(users[ui]);
2130 for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
2131 ServiceRecord sr = alls.valueAt(i);
2132 res.add(makeRunningServiceInfoLocked(sr));
Dianne Hackborn0c380492012-08-20 17:23:30 -07002133 }
2134 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002135
Dianne Hackborn0c380492012-08-20 17:23:30 -07002136 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
2137 ServiceRecord r = mRestartingServices.get(i);
2138 ActivityManager.RunningServiceInfo info =
2139 makeRunningServiceInfoLocked(r);
2140 info.restarting = r.nextRestartTime;
2141 res.add(info);
2142 }
2143 } else {
2144 int userId = UserHandle.getUserId(uid);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002145 ArrayMap<ComponentName, ServiceRecord> alls = getServices(userId);
2146 for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
2147 ServiceRecord sr = alls.valueAt(i);
2148 res.add(makeRunningServiceInfoLocked(sr));
Dianne Hackborn0c380492012-08-20 17:23:30 -07002149 }
2150
2151 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
2152 ServiceRecord r = mRestartingServices.get(i);
2153 if (r.userId == userId) {
2154 ActivityManager.RunningServiceInfo info =
2155 makeRunningServiceInfoLocked(r);
2156 info.restarting = r.nextRestartTime;
2157 res.add(info);
2158 }
2159 }
2160 }
2161 } finally {
2162 Binder.restoreCallingIdentity(ident);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002163 }
2164
2165 return res;
2166 }
2167
2168 public PendingIntent getRunningServiceControlPanelLocked(ComponentName name) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07002169 int userId = UserHandle.getUserId(Binder.getCallingUid());
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002170 ServiceRecord r = getServiceByName(name, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002171 if (r != null) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002172 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2173 ArrayList<ConnectionRecord> conn = r.connections.valueAt(conni);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002174 for (int i=0; i<conn.size(); i++) {
2175 if (conn.get(i).clientIntent != null) {
2176 return conn.get(i).clientIntent;
2177 }
2178 }
2179 }
2180 }
2181 return null;
2182 }
2183
2184 void serviceTimeout(ProcessRecord proc) {
2185 String anrMessage = null;
2186
2187 synchronized(this) {
2188 if (proc.executingServices.size() == 0 || proc.thread == null) {
2189 return;
2190 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002191 long maxTime = SystemClock.uptimeMillis() -
2192 (proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002193 ServiceRecord timeout = null;
2194 long nextTime = 0;
Dianne Hackbornc8230512013-07-13 21:32:12 -07002195 for (int i=proc.executingServices.size()-1; i>=0; i--) {
2196 ServiceRecord sr = proc.executingServices.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002197 if (sr.executingStart < maxTime) {
2198 timeout = sr;
2199 break;
2200 }
2201 if (sr.executingStart > nextTime) {
2202 nextTime = sr.executingStart;
2203 }
2204 }
2205 if (timeout != null && mAm.mLruProcesses.contains(proc)) {
2206 Slog.w(TAG, "Timeout executing service: " + timeout);
2207 anrMessage = "Executing service " + timeout.shortName;
2208 } else {
2209 Message msg = mAm.mHandler.obtainMessage(
2210 ActivityManagerService.SERVICE_TIMEOUT_MSG);
2211 msg.obj = proc;
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002212 mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg
Dianne Hackborn2be00932013-09-22 16:46:00 -07002213 ? (nextTime+SERVICE_TIMEOUT) : (nextTime + SERVICE_BACKGROUND_TIMEOUT));
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002214 }
2215 }
2216
2217 if (anrMessage != null) {
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -07002218 mAm.appNotResponding(proc, null, null, false, anrMessage);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002219 }
2220 }
2221
Dianne Hackborn2be00932013-09-22 16:46:00 -07002222 void scheduleServiceTimeoutLocked(ProcessRecord proc) {
2223 if (proc.executingServices.size() == 0 || proc.thread == null) {
2224 return;
2225 }
2226 long now = SystemClock.uptimeMillis();
2227 Message msg = mAm.mHandler.obtainMessage(
2228 ActivityManagerService.SERVICE_TIMEOUT_MSG);
2229 msg.obj = proc;
2230 mAm.mHandler.sendMessageAtTime(msg,
2231 proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
2232 }
2233
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002234 /**
2235 * Prints a list of ServiceRecords (dumpsys activity services)
2236 */
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002237 void dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002238 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
2239 boolean needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002240 boolean printedAnything = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002241
2242 ItemMatcher matcher = new ItemMatcher();
2243 matcher.build(args, opti);
2244
2245 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
2246 try {
Dianne Hackborn1676c852012-09-10 14:52:30 -07002247 int[] users = mAm.getUsersLocked();
2248 for (int user : users) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002249 ServiceMap smap = getServiceMap(user);
2250 boolean printed = false;
2251 if (smap.mServicesByName.size() > 0) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002252 long nowReal = SystemClock.elapsedRealtime();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002253 needSep = false;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002254 for (int si=0; si<smap.mServicesByName.size(); si++) {
2255 ServiceRecord r = smap.mServicesByName.valueAt(si);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002256 if (!matcher.match(r, r.name)) {
2257 continue;
2258 }
2259 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2260 continue;
2261 }
2262 if (!printed) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002263 if (printedAnything) {
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07002264 pw.println();
2265 }
Dianne Hackborn1676c852012-09-10 14:52:30 -07002266 pw.println(" User " + user + " active services:");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002267 printed = true;
2268 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002269 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002270 if (needSep) {
2271 pw.println();
2272 }
2273 pw.print(" * ");
2274 pw.println(r);
2275 if (dumpAll) {
2276 r.dump(pw, " ");
2277 needSep = true;
2278 } else {
2279 pw.print(" app=");
2280 pw.println(r.app);
2281 pw.print(" created=");
2282 TimeUtils.formatDuration(r.createTime, nowReal, pw);
2283 pw.print(" started=");
2284 pw.print(r.startRequested);
2285 pw.print(" connections=");
2286 pw.println(r.connections.size());
2287 if (r.connections.size() > 0) {
2288 pw.println(" Connections:");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002289 for (int conni=0; conni<r.connections.size(); conni++) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002290 ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002291 for (int i = 0; i < clist.size(); i++) {
2292 ConnectionRecord conn = clist.get(i);
2293 pw.print(" ");
2294 pw.print(conn.binding.intent.intent.getIntent()
2295 .toShortString(false, false, false, false));
2296 pw.print(" -> ");
2297 ProcessRecord proc = conn.binding.client;
2298 pw.println(proc != null ? proc.toShortString() : "null");
2299 }
2300 }
2301 }
2302 }
2303 if (dumpClient && r.app != null && r.app.thread != null) {
2304 pw.println(" Client:");
2305 pw.flush();
2306 try {
2307 TransferPipe tp = new TransferPipe();
2308 try {
2309 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(),
2310 r, args);
2311 tp.setBufferPrefix(" ");
2312 // Short timeout, since blocking here can
2313 // deadlock with the application.
2314 tp.go(fd, 2000);
2315 } finally {
2316 tp.kill();
2317 }
2318 } catch (IOException e) {
2319 pw.println(" Failure while dumping the service: " + e);
2320 } catch (RemoteException e) {
2321 pw.println(" Got a RemoteException while dumping the service");
2322 }
2323 needSep = true;
2324 }
2325 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002326 needSep |= printed;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002327 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002328 printed = false;
2329 for (int si=0, SN=smap.mDelayedStartList.size(); si<SN; si++) {
2330 ServiceRecord r = smap.mDelayedStartList.get(si);
2331 if (!matcher.match(r, r.name)) {
2332 continue;
2333 }
2334 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2335 continue;
2336 }
2337 if (!printed) {
2338 if (printedAnything) {
2339 pw.println();
2340 }
2341 pw.println(" User " + user + " delayed start services:");
2342 printed = true;
2343 }
2344 printedAnything = true;
2345 pw.print(" * Delayed start "); pw.println(r);
2346 }
2347 printed = false;
2348 for (int si=0, SN=smap.mStartingBackground.size(); si<SN; si++) {
2349 ServiceRecord r = smap.mStartingBackground.get(si);
2350 if (!matcher.match(r, r.name)) {
2351 continue;
2352 }
2353 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2354 continue;
2355 }
2356 if (!printed) {
2357 if (printedAnything) {
2358 pw.println();
2359 }
2360 pw.println(" User " + user + " starting in background:");
2361 printed = true;
2362 }
2363 printedAnything = true;
2364 pw.print(" * Starting bg "); pw.println(r);
2365 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002366 }
Amith Yamasani258848d2012-08-10 17:06:33 -07002367 } catch (Exception e) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002368 Slog.w(TAG, "Exception in dumpServicesLocked", e);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002369 }
2370
2371 if (mPendingServices.size() > 0) {
2372 boolean printed = false;
2373 for (int i=0; i<mPendingServices.size(); i++) {
2374 ServiceRecord r = mPendingServices.get(i);
2375 if (!matcher.match(r, r.name)) {
2376 continue;
2377 }
2378 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2379 continue;
2380 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002381 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002382 if (!printed) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002383 if (needSep) pw.println();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002384 needSep = true;
2385 pw.println(" Pending services:");
2386 printed = true;
2387 }
2388 pw.print(" * Pending "); pw.println(r);
2389 r.dump(pw, " ");
2390 }
2391 needSep = true;
2392 }
2393
2394 if (mRestartingServices.size() > 0) {
2395 boolean printed = false;
2396 for (int i=0; i<mRestartingServices.size(); i++) {
2397 ServiceRecord r = mRestartingServices.get(i);
2398 if (!matcher.match(r, r.name)) {
2399 continue;
2400 }
2401 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2402 continue;
2403 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002404 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002405 if (!printed) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002406 if (needSep) pw.println();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002407 needSep = true;
2408 pw.println(" Restarting services:");
2409 printed = true;
2410 }
2411 pw.print(" * Restarting "); pw.println(r);
2412 r.dump(pw, " ");
2413 }
2414 needSep = true;
2415 }
2416
Dianne Hackborn164371f2013-10-01 19:10:13 -07002417 if (mDestroyingServices.size() > 0) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002418 boolean printed = false;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002419 for (int i=0; i< mDestroyingServices.size(); i++) {
2420 ServiceRecord r = mDestroyingServices.get(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002421 if (!matcher.match(r, r.name)) {
2422 continue;
2423 }
2424 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2425 continue;
2426 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002427 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002428 if (!printed) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002429 if (needSep) pw.println();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002430 needSep = true;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002431 pw.println(" Destroying services:");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002432 printed = true;
2433 }
Dianne Hackborn164371f2013-10-01 19:10:13 -07002434 pw.print(" * Destroy "); pw.println(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002435 r.dump(pw, " ");
2436 }
2437 needSep = true;
2438 }
2439
2440 if (dumpAll) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002441 boolean printed = false;
2442 for (int ic=0; ic<mServiceConnections.size(); ic++) {
2443 ArrayList<ConnectionRecord> r = mServiceConnections.valueAt(ic);
2444 for (int i=0; i<r.size(); i++) {
2445 ConnectionRecord cr = r.get(i);
2446 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
2447 continue;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002448 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002449 if (dumpPackage != null && (cr.binding.client == null
2450 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
2451 continue;
2452 }
2453 printedAnything = true;
2454 if (!printed) {
2455 if (needSep) pw.println();
2456 needSep = true;
2457 pw.println(" Connection bindings to services:");
2458 printed = true;
2459 }
2460 pw.print(" * "); pw.println(cr);
2461 cr.dump(pw, " ");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002462 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002463 }
2464 }
2465
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002466 if (!printedAnything) {
2467 pw.println(" (nothing)");
2468 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002469 }
2470
2471 /**
2472 * There are three ways to call this:
2473 * - no service specified: dump all the services
2474 * - a flattened component name that matched an existing service was specified as the
2475 * first arg: dump that one service
2476 * - the first arg isn't the flattened component name of an existing service:
2477 * dump all services whose component contains the first arg as a substring
2478 */
2479 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
2480 int opti, boolean dumpAll) {
2481 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
2482
Dianne Hackborn1676c852012-09-10 14:52:30 -07002483 synchronized (this) {
2484 int[] users = mAm.getUsersLocked();
2485 if ("all".equals(name)) {
2486 for (int user : users) {
Dianne Hackborn13c590d2013-10-07 14:32:00 -07002487 ServiceMap smap = mServiceMap.get(user);
2488 if (smap == null) {
2489 continue;
2490 }
2491 ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002492 for (int i=0; i<alls.size(); i++) {
2493 ServiceRecord r1 = alls.valueAt(i);
Amith Yamasani258848d2012-08-10 17:06:33 -07002494 services.add(r1);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002495 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002496 }
Dianne Hackborn1676c852012-09-10 14:52:30 -07002497 } else {
2498 ComponentName componentName = name != null
2499 ? ComponentName.unflattenFromString(name) : null;
2500 int objectId = 0;
2501 if (componentName == null) {
2502 // Not a '/' separated full component name; maybe an object ID?
2503 try {
2504 objectId = Integer.parseInt(name, 16);
2505 name = null;
2506 componentName = null;
2507 } catch (RuntimeException e) {
2508 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002509 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002510
Dianne Hackborn1676c852012-09-10 14:52:30 -07002511 for (int user : users) {
Dianne Hackborn13c590d2013-10-07 14:32:00 -07002512 ServiceMap smap = mServiceMap.get(user);
2513 if (smap == null) {
2514 continue;
2515 }
2516 ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002517 for (int i=0; i<alls.size(); i++) {
2518 ServiceRecord r1 = alls.valueAt(i);
Amith Yamasani258848d2012-08-10 17:06:33 -07002519 if (componentName != null) {
2520 if (r1.name.equals(componentName)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002521 services.add(r1);
2522 }
Amith Yamasani258848d2012-08-10 17:06:33 -07002523 } else if (name != null) {
2524 if (r1.name.flattenToString().contains(name)) {
2525 services.add(r1);
2526 }
2527 } else if (System.identityHashCode(r1) == objectId) {
2528 services.add(r1);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002529 }
2530 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002531 }
2532 }
2533 }
2534
2535 if (services.size() <= 0) {
2536 return false;
2537 }
2538
2539 boolean needSep = false;
2540 for (int i=0; i<services.size(); i++) {
2541 if (needSep) {
2542 pw.println();
2543 }
2544 needSep = true;
2545 dumpService("", fd, pw, services.get(i), args, dumpAll);
2546 }
2547 return true;
2548 }
2549
2550 /**
2551 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
2552 * there is a thread associated with the service.
2553 */
2554 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
2555 final ServiceRecord r, String[] args, boolean dumpAll) {
2556 String innerPrefix = prefix + " ";
2557 synchronized (this) {
2558 pw.print(prefix); pw.print("SERVICE ");
2559 pw.print(r.shortName); pw.print(" ");
2560 pw.print(Integer.toHexString(System.identityHashCode(r)));
2561 pw.print(" pid=");
2562 if (r.app != null) pw.println(r.app.pid);
2563 else pw.println("(not running)");
2564 if (dumpAll) {
2565 r.dump(pw, innerPrefix);
2566 }
2567 }
2568 if (r.app != null && r.app.thread != null) {
2569 pw.print(prefix); pw.println(" Client:");
2570 pw.flush();
2571 try {
2572 TransferPipe tp = new TransferPipe();
2573 try {
2574 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
2575 tp.setBufferPrefix(prefix + " ");
2576 tp.go(fd);
2577 } finally {
2578 tp.kill();
2579 }
2580 } catch (IOException e) {
2581 pw.println(prefix + " Failure while dumping the service: " + e);
2582 } catch (RemoteException e) {
2583 pw.println(prefix + " Got a RemoteException while dumping the service");
2584 }
2585 }
2586 }
2587
2588}