blob: b87e109b549ffbf857470f81e872b73dbddce7ad [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
Wale Ogunwaled57969f2014-11-15 19:37:29 -080019import static com.android.server.am.ActivityManagerDebugConfig.*;
20
Dianne Hackborn599db5c2012-08-03 19:28:48 -070021import java.io.FileDescriptor;
22import java.io.IOException;
23import java.io.PrintWriter;
Dianne Hackborncff1bbf2015-01-20 13:43:32 -080024import java.io.StringWriter;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070025import java.util.ArrayList;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070026import java.util.HashSet;
27import java.util.Iterator;
28import java.util.List;
Wale Ogunwale540e1232015-05-01 15:35:39 -070029import java.util.Set;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070030
Dianne Hackborn455625e2015-01-21 09:55:13 -080031import android.app.ActivityThread;
Svet Ganov99b60432015-06-27 13:15:22 -070032import android.app.AppOpsManager;
Christoph Studer365e4c32014-09-18 20:35:36 +020033import android.os.Build;
Craig Mautner4a8dddbf2014-08-13 10:49:26 -070034import android.os.DeadObjectException;
Dianne Hackborn9210bc82013-09-05 12:31:16 -070035import android.os.Handler;
Dianne Hackborn13c590d2013-10-07 14:32:00 -070036import android.os.Looper;
Dianne Hackborn23037412013-11-04 18:11:29 -080037import android.os.SystemProperties;
Craig Mautner5f2bb4c2015-03-12 16:10:27 -070038import android.os.TransactionTooLargeException;
Dianne Hackborn9210bc82013-09-05 12:31:16 -070039import android.util.ArrayMap;
Dianne Hackborn465fa392014-09-14 14:21:18 -070040import android.util.ArraySet;
Wale Ogunwaled57969f2014-11-15 19:37:29 -080041
Dianne Hackbornd2932242013-08-05 18:18:42 -070042import com.android.internal.app.ProcessStats;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070043import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070044import com.android.internal.os.TransferPipe;
Dianne Hackborncff1bbf2015-01-20 13:43:32 -080045import com.android.internal.util.FastPrintWriter;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070046import com.android.server.am.ActivityManagerService.ItemMatcher;
47import com.android.server.am.ActivityManagerService.NeededUriGrants;
48
49import android.app.ActivityManager;
50import android.app.AppGlobals;
51import android.app.IApplicationThread;
52import android.app.IServiceConnection;
53import android.app.Notification;
54import android.app.PendingIntent;
55import android.app.Service;
56import android.content.ComponentName;
57import android.content.Context;
58import android.content.Intent;
59import android.content.pm.ApplicationInfo;
60import android.content.pm.PackageManager;
61import android.content.pm.ResolveInfo;
62import android.content.pm.ServiceInfo;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070063import android.os.Binder;
64import android.os.IBinder;
65import android.os.Message;
66import android.os.Process;
67import android.os.RemoteException;
68import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070069import android.os.UserHandle;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070070import android.util.EventLog;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070071import android.util.Slog;
72import android.util.SparseArray;
73import android.util.TimeUtils;
74
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -070075public final class ActiveServices {
Wale Ogunwaled57969f2014-11-15 19:37:29 -080076 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActiveServices" : TAG_AM;
77 private static final String TAG_MU = TAG + POSTFIX_MU;
78 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
79 private static final String TAG_SERVICE_EXECUTING = TAG + POSTFIX_SERVICE_EXECUTING;
80
81 private static final boolean DEBUG_DELAYED_SERVICE = DEBUG_SERVICE;
82 private static final boolean DEBUG_DELAYED_STARTS = DEBUG_DELAYED_SERVICE;
83
84 private static final boolean LOG_SERVICE_START_STOP = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070085
86 // How long we wait for a service to finish executing.
87 static final int SERVICE_TIMEOUT = 20*1000;
88
Dianne Hackbornbf36ee22013-07-26 18:24:10 -070089 // How long we wait for a service to finish executing.
90 static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
91
Dianne Hackborn599db5c2012-08-03 19:28:48 -070092 // How long a service needs to be running until restarting its process
93 // is no longer considered to be a relaunch of the service.
Dianne Hackborn7b492722013-11-01 09:58:45 -070094 static final int SERVICE_RESTART_DURATION = 1*1000;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070095
96 // How long a service needs to be running until it will start back at
97 // SERVICE_RESTART_DURATION after being killed.
98 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
99
100 // Multiplying factor to increase restart duration time by, for each time
101 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
102 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
103
104 // The minimum amount of time between restarting services that we allow.
105 // That is, when multiple services are restarting, we won't allow each
106 // to restart less than this amount of time from the last one.
107 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
108
109 // Maximum amount of time for there to be no activity on a service before
110 // we consider it non-essential and allow its process to go on the
111 // LRU background list.
112 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
113
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700114 // How long we wait for a background started service to stop itself before
115 // allowing the next pending start to run.
116 static final int BG_START_TIMEOUT = 15*1000;
117
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700118 final ActivityManagerService mAm;
119
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700120 // Maximum number of services that we allow to start in the background
121 // at the same time.
122 final int mMaxStartingBackground;
123
Wale Ogunwale540e1232015-05-01 15:35:39 -0700124 final SparseArray<ServiceMap> mServiceMap = new SparseArray<>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700125
126 /**
127 * All currently bound service connections. Keys are the IBinder of
128 * the client's IServiceConnection.
129 */
Wale Ogunwale540e1232015-05-01 15:35:39 -0700130 final ArrayMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections = new ArrayMap<>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700131
132 /**
133 * List of services that we have been asked to start,
134 * but haven't yet been able to. It is used to hold start requests
135 * while waiting for their corresponding application thread to get
136 * going.
137 */
Wale Ogunwale540e1232015-05-01 15:35:39 -0700138 final ArrayList<ServiceRecord> mPendingServices = new ArrayList<>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700139
140 /**
141 * List of services that are scheduled to restart following a crash.
142 */
Wale Ogunwale540e1232015-05-01 15:35:39 -0700143 final ArrayList<ServiceRecord> mRestartingServices = new ArrayList<>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700144
145 /**
Dianne Hackborn164371f2013-10-01 19:10:13 -0700146 * List of services that are in the process of being destroyed.
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700147 */
Wale Ogunwale540e1232015-05-01 15:35:39 -0700148 final ArrayList<ServiceRecord> mDestroyingServices = new ArrayList<>();
149
150 /** Temporary list for holding the results of calls to {@link #collectPackageServicesLocked} */
151 private ArrayList<ServiceRecord> mTmpCollectionResults = null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700152
Dianne Hackborncff1bbf2015-01-20 13:43:32 -0800153 /** Amount of time to allow a last ANR message to exist before freeing the memory. */
154 static final int LAST_ANR_LIFETIME_DURATION_MSECS = 2 * 60 * 60 * 1000; // Two hours
155
156 String mLastAnrDump;
157
158 final Runnable mLastAnrDumpClearer = new Runnable() {
159 @Override public void run() {
160 synchronized (mAm) {
161 mLastAnrDump = null;
162 }
163 }
164 };
165
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700166 /**
167 * Information about services for a single user.
168 */
169 class ServiceMap extends Handler {
Dianne Hackborn6285a322013-09-18 12:09:47 -0700170 final int mUserId;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700171 final ArrayMap<ComponentName, ServiceRecord> mServicesByName
172 = new ArrayMap<ComponentName, ServiceRecord>();
173 final ArrayMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent
174 = new ArrayMap<Intent.FilterComparison, ServiceRecord>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700175
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700176 final ArrayList<ServiceRecord> mDelayedStartList
177 = new ArrayList<ServiceRecord>();
178 /* XXX eventually I'd like to have this based on processes instead of services.
179 * That is, if we try to start two services in a row both running in the same
180 * process, this should be one entry in mStartingBackground for that one process
181 * that remains until all services in it are done.
182 final ArrayMap<ProcessRecord, DelayingProcess> mStartingBackgroundMap
183 = new ArrayMap<ProcessRecord, DelayingProcess>();
184 final ArrayList<DelayingProcess> mStartingProcessList
185 = new ArrayList<DelayingProcess>();
186 */
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700187
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700188 final ArrayList<ServiceRecord> mStartingBackground
189 = new ArrayList<ServiceRecord>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700190
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700191 static final int MSG_BG_START_TIMEOUT = 1;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700192
Dianne Hackborn13c590d2013-10-07 14:32:00 -0700193 ServiceMap(Looper looper, int userId) {
194 super(looper);
Dianne Hackborn6285a322013-09-18 12:09:47 -0700195 mUserId = userId;
196 }
197
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700198 @Override
199 public void handleMessage(Message msg) {
200 switch (msg.what) {
201 case MSG_BG_START_TIMEOUT: {
202 synchronized (mAm) {
203 rescheduleDelayedStarts();
204 }
205 } break;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700206 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700207 }
208
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700209 void ensureNotStartingBackground(ServiceRecord r) {
210 if (mStartingBackground.remove(r)) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800211 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
212 "No longer background starting: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700213 rescheduleDelayedStarts();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700214 }
Dianne Hackborn2e46bb52013-09-13 17:01:26 -0700215 if (mDelayedStartList.remove(r)) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800216 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "No longer delaying start: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700217 }
218 }
219
220 void rescheduleDelayedStarts() {
221 removeMessages(MSG_BG_START_TIMEOUT);
222 final long now = SystemClock.uptimeMillis();
223 for (int i=0, N=mStartingBackground.size(); i<N; i++) {
224 ServiceRecord r = mStartingBackground.get(i);
225 if (r.startingBgTimeout <= now) {
226 Slog.i(TAG, "Waited long enough for: " + r);
227 mStartingBackground.remove(i);
228 N--;
Junu Kimfcb87362014-02-19 16:25:21 +0900229 i--;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700230 }
231 }
232 while (mDelayedStartList.size() > 0
233 && mStartingBackground.size() < mMaxStartingBackground) {
234 ServiceRecord r = mDelayedStartList.remove(0);
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800235 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
236 "REM FR DELAY LIST (exec next): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700237 if (r.pendingStarts.size() <= 0) {
238 Slog.w(TAG, "**** NO PENDING STARTS! " + r + " startReq=" + r.startRequested
239 + " delayedStop=" + r.delayedStop);
240 }
241 if (DEBUG_DELAYED_SERVICE) {
242 if (mDelayedStartList.size() > 0) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800243 Slog.v(TAG_SERVICE, "Remaining delayed list:");
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700244 for (int i=0; i<mDelayedStartList.size(); i++) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800245 Slog.v(TAG_SERVICE, " #" + i + ": " + mDelayedStartList.get(i));
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700246 }
247 }
248 }
249 r.delayed = false;
Craig Mautner5f2bb4c2015-03-12 16:10:27 -0700250 try {
251 startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false, true);
252 } catch (TransactionTooLargeException e) {
253 // Ignore, nobody upstack cares.
254 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700255 }
256 if (mStartingBackground.size() > 0) {
257 ServiceRecord next = mStartingBackground.get(0);
258 long when = next.startingBgTimeout > now ? next.startingBgTimeout : now;
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800259 if (DEBUG_DELAYED_SERVICE) Slog.v(TAG_SERVICE, "Top bg start is " + next
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700260 + ", can delay others up to " + when);
261 Message msg = obtainMessage(MSG_BG_START_TIMEOUT);
262 sendMessageAtTime(msg, when);
263 }
Dianne Hackborn6285a322013-09-18 12:09:47 -0700264 if (mStartingBackground.size() < mMaxStartingBackground) {
265 mAm.backgroundServicesFinishedLocked(mUserId);
266 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700267 }
268 }
269
270 public ActiveServices(ActivityManagerService service) {
271 mAm = service;
Dianne Hackborn23037412013-11-04 18:11:29 -0800272 int maxBg = 0;
273 try {
274 maxBg = Integer.parseInt(SystemProperties.get("ro.config.max_starting_bg", "0"));
275 } catch(RuntimeException e) {
276 }
Dianne Hackborn20d94742014-05-29 18:35:45 -0700277 mMaxStartingBackground = maxBg > 0
278 ? maxBg : ActivityManager.isLowRamDeviceStatic() ? 1 : 8;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700279 }
280
281 ServiceRecord getServiceByName(ComponentName name, int callingUser) {
282 // TODO: Deal with global services
283 if (DEBUG_MU)
284 Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
285 return getServiceMap(callingUser).mServicesByName.get(name);
286 }
287
Dianne Hackborn6285a322013-09-18 12:09:47 -0700288 boolean hasBackgroundServices(int callingUser) {
289 ServiceMap smap = mServiceMap.get(callingUser);
290 return smap != null ? smap.mStartingBackground.size() >= mMaxStartingBackground : false;
291 }
292
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700293 private ServiceMap getServiceMap(int callingUser) {
294 ServiceMap smap = mServiceMap.get(callingUser);
295 if (smap == null) {
Dianne Hackborn13c590d2013-10-07 14:32:00 -0700296 smap = new ServiceMap(mAm.mHandler.getLooper(), callingUser);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700297 mServiceMap.put(callingUser, smap);
298 }
299 return smap;
300 }
301
302 ArrayMap<ComponentName, ServiceRecord> getServices(int callingUser) {
303 return getServiceMap(callingUser).mServicesByName;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700304 }
305
Svet Ganov99b60432015-06-27 13:15:22 -0700306 ComponentName startServiceLocked(IApplicationThread caller, Intent service, String resolvedType,
307 int callingPid, int callingUid, String callingPackage, int userId)
Craig Mautner5f2bb4c2015-03-12 16:10:27 -0700308 throws TransactionTooLargeException {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800309 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "startService: " + service
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700310 + " type=" + resolvedType + " args=" + service.getExtras());
311
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700312 final boolean callerFg;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700313 if (caller != null) {
314 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
315 if (callerApp == null) {
316 throw new SecurityException(
317 "Unable to find app for caller " + caller
318 + " (pid=" + Binder.getCallingPid()
319 + ") when starting service " + service);
320 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700321 callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
322 } else {
323 callerFg = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700324 }
325
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700326
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700327 ServiceLookupResult res =
Svet Ganov99b60432015-06-27 13:15:22 -0700328 retrieveServiceLocked(service, resolvedType, callingPackage,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700329 callingPid, callingUid, userId, true, callerFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700330 if (res == null) {
331 return null;
332 }
333 if (res.record == null) {
334 return new ComponentName("!", res.permission != null
335 ? res.permission : "private to package");
336 }
Adam Lesinskieddeb492014-09-08 17:50:03 -0700337
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700338 ServiceRecord r = res.record;
Adam Lesinskieddeb492014-09-08 17:50:03 -0700339
340 if (!mAm.getUserManagerLocked().exists(r.userId)) {
341 Slog.d(TAG, "Trying to start service with non-existent user! " + r.userId);
342 return null;
343 }
344
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700345 NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
Nicolas Prevotc6cf95c2014-05-29 11:30:36 +0100346 callingUid, r.packageName, service, service.getFlags(), null, r.userId);
Dianne Hackbornd6f5b622013-11-11 17:25:37 -0800347 if (unscheduleServiceRestartLocked(r, callingUid, false)) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800348 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "START SERVICE WHILE RESTART PENDING: " + r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700349 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700350 r.lastActivity = SystemClock.uptimeMillis();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700351 r.startRequested = true;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700352 r.delayedStop = false;
353 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
354 service, neededGrants));
355
356 final ServiceMap smap = getServiceMap(r.userId);
357 boolean addToStarting = false;
358 if (!callerFg && r.app == null && mAm.mStartedUsers.get(r.userId) != null) {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700359 ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700360 if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700361 // If this is not coming from a foreground caller, then we may want
362 // to delay the start if there are already other background services
363 // that are starting. This is to avoid process start spam when lots
364 // of applications are all handling things like connectivity broadcasts.
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700365 // We only do this for cached processes, because otherwise an application
366 // can have assumptions about calling startService() for a service to run
367 // in its own process, and for that process to not be killed before the
368 // service is started. This is especially the case for receivers, which
369 // may start a service in onReceive() to do some additional work and have
370 // initialized some global state as part of that.
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800371 if (DEBUG_DELAYED_SERVICE) Slog.v(TAG_SERVICE, "Potential start delay of "
372 + r + " in " + proc);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700373 if (r.delayed) {
374 // This service is already scheduled for a delayed start; just leave
375 // it still waiting.
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800376 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Continuing to delay: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700377 return r.name;
378 }
379 if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
380 // Something else is starting, delay!
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800381 Slog.i(TAG_SERVICE, "Delaying start of: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700382 smap.mDelayedStartList.add(r);
383 r.delayed = true;
384 return r.name;
385 }
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800386 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Not delaying: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700387 addToStarting = true;
388 } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
389 // We slightly loosen when we will enqueue this new service as a background
390 // starting service we are waiting for, to also include processes that are
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700391 // currently running other services or receivers.
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700392 addToStarting = true;
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800393 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
394 "Not delaying, but counting as bg: " + r);
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800395 } else if (DEBUG_DELAYED_STARTS) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700396 StringBuilder sb = new StringBuilder(128);
397 sb.append("Not potential delay (state=").append(proc.curProcState)
398 .append(' ').append(proc.adjType);
399 String reason = proc.makeAdjReason();
400 if (reason != null) {
401 sb.append(' ');
402 sb.append(reason);
403 }
404 sb.append("): ");
405 sb.append(r.toString());
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800406 Slog.v(TAG_SERVICE, sb.toString());
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700407 }
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800408 } else if (DEBUG_DELAYED_STARTS) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700409 if (callerFg) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800410 Slog.v(TAG_SERVICE, "Not potential delay (callerFg=" + callerFg + " uid="
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700411 + callingUid + " pid=" + callingPid + "): " + r);
412 } else if (r.app != null) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800413 Slog.v(TAG_SERVICE, "Not potential delay (cur app=" + r.app + "): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700414 } else {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800415 Slog.v(TAG_SERVICE,
416 "Not potential delay (user " + r.userId + " not started): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700417 }
418 }
419
420 return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
421 }
422
Craig Mautner5f2bb4c2015-03-12 16:10:27 -0700423 ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
424 boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700425 ProcessStats.ServiceState stracker = r.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -0700426 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700427 stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700428 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700429 r.callStart = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700430 synchronized (r.stats.getBatteryStats()) {
431 r.stats.startRunningLocked();
432 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700433 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -0700434 if (error != null) {
435 return new ComponentName("!!", error);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700436 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700437
438 if (r.startRequested && addToStarting) {
439 boolean first = smap.mStartingBackground.size() == 0;
440 smap.mStartingBackground.add(r);
441 r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
442 if (DEBUG_DELAYED_SERVICE) {
443 RuntimeException here = new RuntimeException("here");
444 here.fillInStackTrace();
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800445 Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r, here);
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800446 } else if (DEBUG_DELAYED_STARTS) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800447 Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700448 }
449 if (first) {
450 smap.rescheduleDelayedStarts();
451 }
452 } else if (callerFg) {
453 smap.ensureNotStartingBackground(r);
454 }
455
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700456 return r.name;
457 }
458
459 private void stopServiceLocked(ServiceRecord service) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700460 if (service.delayed) {
461 // If service isn't actually running, but is is being held in the
462 // delayed list, then we need to keep it started but note that it
463 // should be stopped once no longer delayed.
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800464 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Delaying stop of pending: " + service);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700465 service.delayedStop = true;
466 return;
467 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700468 synchronized (service.stats.getBatteryStats()) {
469 service.stats.stopRunningLocked();
470 }
471 service.startRequested = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700472 if (service.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700473 service.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700474 SystemClock.uptimeMillis());
475 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700476 service.callStart = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700477 bringDownServiceIfNeededLocked(service, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700478 }
479
480 int stopServiceLocked(IApplicationThread caller, Intent service,
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700481 String resolvedType, int userId) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800482 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "stopService: " + service
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700483 + " type=" + resolvedType);
484
485 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
486 if (caller != null && callerApp == null) {
487 throw new SecurityException(
488 "Unable to find app for caller " + caller
489 + " (pid=" + Binder.getCallingPid()
490 + ") when stopping service " + service);
491 }
492
493 // If this service is active, make sure it is stopped.
Svet Ganov99b60432015-06-27 13:15:22 -0700494 ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, null,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700495 Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700496 if (r != null) {
497 if (r.record != null) {
498 final long origId = Binder.clearCallingIdentity();
499 try {
500 stopServiceLocked(r.record);
501 } finally {
502 Binder.restoreCallingIdentity(origId);
503 }
504 return 1;
505 }
506 return -1;
507 }
508
509 return 0;
510 }
511
Svet Ganov99b60432015-06-27 13:15:22 -0700512 IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) {
513 ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, callingPackage,
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -0700514 Binder.getCallingPid(), Binder.getCallingUid(),
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700515 UserHandle.getCallingUserId(), false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700516
517 IBinder ret = null;
518 if (r != null) {
519 // r.record is null if findServiceLocked() failed the caller permission check
520 if (r.record == null) {
521 throw new SecurityException(
Christopher Desjardins5862c5f2015-05-19 11:25:40 +0000522 "Permission Denial: Accessing service"
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700523 + " from pid=" + Binder.getCallingPid()
524 + ", uid=" + Binder.getCallingUid()
525 + " requires " + r.permission);
526 }
527 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
528 if (ib != null) {
529 ret = ib.binder;
530 }
531 }
532
533 return ret;
534 }
535
536 boolean stopServiceTokenLocked(ComponentName className, IBinder token,
537 int startId) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800538 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "stopServiceToken: " + className
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700539 + " " + token + " startId=" + startId);
Dianne Hackborn41203752012-08-31 14:05:51 -0700540 ServiceRecord r = findServiceLocked(className, token, UserHandle.getCallingUserId());
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700541 if (r != null) {
542 if (startId >= 0) {
543 // Asked to only stop if done with all work. Note that
544 // to avoid leaks, we will take this as dropping all
545 // start items up to and including this one.
546 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
547 if (si != null) {
548 while (r.deliveredStarts.size() > 0) {
549 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
550 cur.removeUriPermissionsLocked();
551 if (cur == si) {
552 break;
553 }
554 }
555 }
556
557 if (r.getLastStartId() != startId) {
558 return false;
559 }
560
561 if (r.deliveredStarts.size() > 0) {
562 Slog.w(TAG, "stopServiceToken startId " + startId
563 + " is last, but have " + r.deliveredStarts.size()
564 + " remaining args");
565 }
566 }
567
568 synchronized (r.stats.getBatteryStats()) {
569 r.stats.stopRunningLocked();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700570 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700571 r.startRequested = false;
572 if (r.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700573 r.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700574 SystemClock.uptimeMillis());
575 }
576 r.callStart = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700577 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700578 bringDownServiceIfNeededLocked(r, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700579 Binder.restoreCallingIdentity(origId);
580 return true;
581 }
582 return false;
583 }
584
585 public void setServiceForegroundLocked(ComponentName className, IBinder token,
586 int id, Notification notification, boolean removeNotification) {
Dianne Hackborn41203752012-08-31 14:05:51 -0700587 final int userId = UserHandle.getCallingUserId();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700588 final long origId = Binder.clearCallingIdentity();
589 try {
Dianne Hackborn41203752012-08-31 14:05:51 -0700590 ServiceRecord r = findServiceLocked(className, token, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700591 if (r != null) {
592 if (id != 0) {
593 if (notification == null) {
594 throw new IllegalArgumentException("null notification");
595 }
596 if (r.foregroundId != id) {
597 r.cancelNotification();
598 r.foregroundId = id;
599 }
600 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
601 r.foregroundNoti = notification;
602 r.isForeground = true;
603 r.postNotification();
604 if (r.app != null) {
605 updateServiceForegroundLocked(r.app, true);
606 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700607 getServiceMap(r.userId).ensureNotStartingBackground(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700608 } else {
609 if (r.isForeground) {
610 r.isForeground = false;
611 if (r.app != null) {
Dianne Hackborndb926082013-10-31 16:32:44 -0700612 mAm.updateLruProcessLocked(r.app, false, null);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700613 updateServiceForegroundLocked(r.app, true);
614 }
615 }
616 if (removeNotification) {
617 r.cancelNotification();
618 r.foregroundId = 0;
619 r.foregroundNoti = null;
Dianne Hackborn955d8d62014-10-07 20:17:19 -0700620 } else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
Christoph Studer365e4c32014-09-18 20:35:36 +0200621 r.stripForegroundServiceFlagFromNotification();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700622 }
623 }
624 }
625 } finally {
626 Binder.restoreCallingIdentity(origId);
627 }
628 }
629
630 private void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
631 boolean anyForeground = false;
Dianne Hackbornc8230512013-07-13 21:32:12 -0700632 for (int i=proc.services.size()-1; i>=0; i--) {
633 ServiceRecord sr = proc.services.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700634 if (sr.isForeground) {
635 anyForeground = true;
636 break;
637 }
638 }
Dianne Hackborneaf2ac42014-02-07 13:01:07 -0800639 mAm.updateProcessForegroundLocked(proc, anyForeground, oomAdj);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700640 }
641
Dianne Hackborn465fa392014-09-14 14:21:18 -0700642 public void updateServiceConnectionActivitiesLocked(ProcessRecord clientProc) {
643 ArraySet<ProcessRecord> updatedProcesses = null;
644 for (int i=0; i<clientProc.connections.size(); i++) {
645 final ConnectionRecord conn = clientProc.connections.valueAt(i);
646 final ProcessRecord proc = conn.binding.service.app;
647 if (proc == null || proc == clientProc) {
648 continue;
649 } else if (updatedProcesses == null) {
650 updatedProcesses = new ArraySet<>();
651 } else if (updatedProcesses.contains(proc)) {
652 continue;
653 }
654 updatedProcesses.add(proc);
655 updateServiceClientActivitiesLocked(proc, null, false);
656 }
657 }
658
Dianne Hackborndb926082013-10-31 16:32:44 -0700659 private boolean updateServiceClientActivitiesLocked(ProcessRecord proc,
Dianne Hackborn465fa392014-09-14 14:21:18 -0700660 ConnectionRecord modCr, boolean updateLru) {
Dianne Hackborndb926082013-10-31 16:32:44 -0700661 if (modCr != null && modCr.binding.client != null) {
662 if (modCr.binding.client.activities.size() <= 0) {
663 // This connection is from a client without activities, so adding
664 // and removing is not interesting.
665 return false;
666 }
667 }
668
669 boolean anyClientActivities = false;
670 for (int i=proc.services.size()-1; i>=0 && !anyClientActivities; i--) {
671 ServiceRecord sr = proc.services.valueAt(i);
672 for (int conni=sr.connections.size()-1; conni>=0 && !anyClientActivities; conni--) {
673 ArrayList<ConnectionRecord> clist = sr.connections.valueAt(conni);
674 for (int cri=clist.size()-1; cri>=0; cri--) {
675 ConnectionRecord cr = clist.get(cri);
676 if (cr.binding.client == null || cr.binding.client == proc) {
677 // Binding to ourself is not interesting.
678 continue;
679 }
680 if (cr.binding.client.activities.size() > 0) {
681 anyClientActivities = true;
682 break;
683 }
684 }
685 }
686 }
687 if (anyClientActivities != proc.hasClientActivities) {
688 proc.hasClientActivities = anyClientActivities;
Dianne Hackborn465fa392014-09-14 14:21:18 -0700689 if (updateLru) {
690 mAm.updateLruProcessLocked(proc, anyClientActivities, null);
691 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700692 return true;
693 }
694 return false;
695 }
696
Craig Mautner5f2bb4c2015-03-12 16:10:27 -0700697 int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
Svet Ganov99b60432015-06-27 13:15:22 -0700698 String resolvedType, IServiceConnection connection, int flags,
699 String callingPackage, int userId) throws TransactionTooLargeException {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800700 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700701 + " type=" + resolvedType + " conn=" + connection.asBinder()
702 + " flags=0x" + Integer.toHexString(flags));
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700703 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
704 if (callerApp == null) {
705 throw new SecurityException(
706 "Unable to find app for caller " + caller
707 + " (pid=" + Binder.getCallingPid()
708 + ") when binding service " + service);
709 }
710
711 ActivityRecord activity = null;
712 if (token != null) {
Craig Mautnerd2328952013-03-05 12:46:26 -0800713 activity = ActivityRecord.isInStackLocked(token);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700714 if (activity == null) {
715 Slog.w(TAG, "Binding with unknown activity: " + token);
716 return 0;
717 }
718 }
719
720 int clientLabel = 0;
721 PendingIntent clientIntent = null;
722
723 if (callerApp.info.uid == Process.SYSTEM_UID) {
724 // Hacky kind of thing -- allow system stuff to tell us
725 // what they are, so we can report this elsewhere for
726 // others to know why certain services are running.
727 try {
Dianne Hackbornf0f94d12014-03-17 16:04:21 -0700728 clientIntent = service.getParcelableExtra(Intent.EXTRA_CLIENT_INTENT);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700729 } catch (RuntimeException e) {
730 }
731 if (clientIntent != null) {
732 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
733 if (clientLabel != 0) {
734 // There are no useful extras in the intent, trash them.
735 // System code calling with this stuff just needs to know
736 // this will happen.
737 service = service.cloneFilter();
738 }
739 }
740 }
741
Dianne Hackbornf0f94d12014-03-17 16:04:21 -0700742 if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
743 mAm.enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
744 "BIND_TREAT_LIKE_ACTIVITY");
745 }
746
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700747 final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
748
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700749 ServiceLookupResult res =
Svet Ganov99b60432015-06-27 13:15:22 -0700750 retrieveServiceLocked(service, resolvedType, callingPackage,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700751 Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700752 if (res == null) {
753 return 0;
754 }
755 if (res.record == null) {
756 return -1;
757 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700758 ServiceRecord s = res.record;
759
760 final long origId = Binder.clearCallingIdentity();
761
762 try {
Dianne Hackbornd6f5b622013-11-11 17:25:37 -0800763 if (unscheduleServiceRestartLocked(s, callerApp.info.uid, false)) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800764 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700765 + s);
766 }
767
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700768 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
769 s.lastActivity = SystemClock.uptimeMillis();
770 if (!s.hasAutoCreateConnections()) {
771 // This is the first binding, let the tracker know.
Dianne Hackbornd2932242013-08-05 18:18:42 -0700772 ProcessStats.ServiceState stracker = s.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -0700773 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700774 stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700775 s.lastActivity);
776 }
777 }
778 }
779
Dianne Hackbornab2df062015-01-07 13:43:13 -0800780 mAm.startAssociationLocked(callerApp.uid, callerApp.processName,
781 s.appInfo.uid, s.name, s.processName);
782
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700783 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
784 ConnectionRecord c = new ConnectionRecord(b, activity,
785 connection, flags, clientLabel, clientIntent);
786
787 IBinder binder = connection.asBinder();
788 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
789 if (clist == null) {
790 clist = new ArrayList<ConnectionRecord>();
791 s.connections.put(binder, clist);
792 }
793 clist.add(c);
794 b.connections.add(c);
795 if (activity != null) {
796 if (activity.connections == null) {
797 activity.connections = new HashSet<ConnectionRecord>();
798 }
799 activity.connections.add(c);
800 }
801 b.client.connections.add(c);
802 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
803 b.client.hasAboveClient = true;
804 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700805 if (s.app != null) {
Dianne Hackborn465fa392014-09-14 14:21:18 -0700806 updateServiceClientActivitiesLocked(s.app, c, true);
Dianne Hackborndb926082013-10-31 16:32:44 -0700807 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700808 clist = mServiceConnections.get(binder);
809 if (clist == null) {
810 clist = new ArrayList<ConnectionRecord>();
811 mServiceConnections.put(binder, clist);
812 }
813 clist.add(c);
814
815 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
816 s.lastActivity = SystemClock.uptimeMillis();
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700817 if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700818 return 0;
819 }
820 }
821
822 if (s.app != null) {
Dianne Hackbornf0f94d12014-03-17 16:04:21 -0700823 if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
824 s.app.treatLikeActivity = true;
825 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700826 // This could have made the service more important.
Dianne Hackbornf0f94d12014-03-17 16:04:21 -0700827 mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities
828 || s.app.treatLikeActivity, b.client);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700829 mAm.updateOomAdjLocked(s.app);
830 }
831
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800832 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bind " + s + " with " + b
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700833 + ": received=" + b.intent.received
834 + " apps=" + b.intent.apps.size()
835 + " doRebind=" + b.intent.doRebind);
836
837 if (s.app != null && b.intent.received) {
838 // Service is already running, so we can immediately
839 // publish the connection.
840 try {
841 c.conn.connected(s.name, b.intent.binder);
842 } catch (Exception e) {
843 Slog.w(TAG, "Failure sending service " + s.shortName
844 + " to connection " + c.conn.asBinder()
845 + " (in " + c.binding.client.processName + ")", e);
846 }
847
848 // If this is the first app connected back to this binding,
849 // and the service had previously asked to be told when
850 // rebound, then do so.
851 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700852 requestServiceBindingLocked(s, b.intent, callerFg, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700853 }
854 } else if (!b.intent.requested) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700855 requestServiceBindingLocked(s, b.intent, callerFg, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700856 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700857
858 getServiceMap(s.userId).ensureNotStartingBackground(s);
859
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700860 } finally {
861 Binder.restoreCallingIdentity(origId);
862 }
863
864 return 1;
865 }
866
867 void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
868 final long origId = Binder.clearCallingIdentity();
869 try {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800870 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "PUBLISHING " + r
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700871 + " " + intent + ": " + service);
872 if (r != null) {
873 Intent.FilterComparison filter
874 = new Intent.FilterComparison(intent);
875 IntentBindRecord b = r.bindings.get(filter);
876 if (b != null && !b.received) {
877 b.binder = service;
878 b.requested = true;
879 b.received = true;
Dianne Hackborn390517b2013-05-30 15:03:32 -0700880 for (int conni=r.connections.size()-1; conni>=0; conni--) {
881 ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
882 for (int i=0; i<clist.size(); i++) {
883 ConnectionRecord c = clist.get(i);
884 if (!filter.equals(c.binding.intent.intent)) {
885 if (DEBUG_SERVICE) Slog.v(
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800886 TAG_SERVICE, "Not publishing to: " + c);
Dianne Hackborn390517b2013-05-30 15:03:32 -0700887 if (DEBUG_SERVICE) Slog.v(
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800888 TAG_SERVICE, "Bound intent: " + c.binding.intent.intent);
Dianne Hackborn390517b2013-05-30 15:03:32 -0700889 if (DEBUG_SERVICE) Slog.v(
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800890 TAG_SERVICE, "Published intent: " + intent);
Dianne Hackborn390517b2013-05-30 15:03:32 -0700891 continue;
892 }
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800893 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c);
Dianne Hackborn390517b2013-05-30 15:03:32 -0700894 try {
895 c.conn.connected(r.name, service);
896 } catch (Exception e) {
897 Slog.w(TAG, "Failure sending service " + r.name +
898 " to connection " + c.conn.asBinder() +
899 " (in " + c.binding.client.processName + ")", e);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700900 }
901 }
902 }
903 }
904
Dianne Hackborn164371f2013-10-01 19:10:13 -0700905 serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700906 }
907 } finally {
908 Binder.restoreCallingIdentity(origId);
909 }
910 }
911
912 boolean unbindServiceLocked(IServiceConnection connection) {
913 IBinder binder = connection.asBinder();
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800914 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "unbindService: conn=" + binder);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700915 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
916 if (clist == null) {
917 Slog.w(TAG, "Unbind failed: could not find connection for "
918 + connection.asBinder());
919 return false;
920 }
921
922 final long origId = Binder.clearCallingIdentity();
923 try {
924 while (clist.size() > 0) {
925 ConnectionRecord r = clist.get(0);
926 removeConnectionLocked(r, null, null);
Dianne Hackborn25e1eca2014-09-23 10:13:13 -0700927 if (clist.size() > 0 && clist.get(0) == r) {
928 // In case it didn't get removed above, do it now.
929 Slog.wtf(TAG, "Connection " + r + " not removed for binder " + binder);
930 clist.remove(0);
931 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700932
933 if (r.binding.service.app != null) {
934 // This could have made the service less important.
Dianne Hackbornf0f94d12014-03-17 16:04:21 -0700935 if ((r.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
936 r.binding.service.app.treatLikeActivity = true;
937 mAm.updateLruProcessLocked(r.binding.service.app,
938 r.binding.service.app.hasClientActivities
939 || r.binding.service.app.treatLikeActivity, null);
940 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700941 mAm.updateOomAdjLocked(r.binding.service.app);
942 }
943 }
944 } finally {
945 Binder.restoreCallingIdentity(origId);
946 }
947
948 return true;
949 }
950
951 void unbindFinishedLocked(ServiceRecord r, Intent intent, boolean doRebind) {
952 final long origId = Binder.clearCallingIdentity();
953 try {
954 if (r != null) {
955 Intent.FilterComparison filter
956 = new Intent.FilterComparison(intent);
957 IntentBindRecord b = r.bindings.get(filter);
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800958 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "unbindFinished in " + r
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700959 + " at " + b + ": apps="
960 + (b != null ? b.apps.size() : 0));
961
Dianne Hackborn164371f2013-10-01 19:10:13 -0700962 boolean inDestroying = mDestroyingServices.contains(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700963 if (b != null) {
Dianne Hackborn164371f2013-10-01 19:10:13 -0700964 if (b.apps.size() > 0 && !inDestroying) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700965 // Applications have already bound since the last
966 // unbind, so just rebind right here.
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700967 boolean inFg = false;
968 for (int i=b.apps.size()-1; i>=0; i--) {
969 ProcessRecord client = b.apps.valueAt(i).client;
970 if (client != null && client.setSchedGroup
971 != Process.THREAD_GROUP_BG_NONINTERACTIVE) {
972 inFg = true;
973 break;
974 }
975 }
Craig Mautner5f2bb4c2015-03-12 16:10:27 -0700976 try {
977 requestServiceBindingLocked(r, b, inFg, true);
978 } catch (TransactionTooLargeException e) {
979 // Don't pass this back to ActivityThread, it's unrelated.
980 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700981 } else {
982 // Note to tell the service the next time there is
983 // a new client.
984 b.doRebind = true;
985 }
986 }
987
Dianne Hackborn164371f2013-10-01 19:10:13 -0700988 serviceDoneExecutingLocked(r, inDestroying, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700989 }
990 } finally {
991 Binder.restoreCallingIdentity(origId);
992 }
993 }
994
995 private final ServiceRecord findServiceLocked(ComponentName name,
Dianne Hackborn41203752012-08-31 14:05:51 -0700996 IBinder token, int userId) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700997 ServiceRecord r = getServiceByName(name, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700998 return r == token ? r : null;
999 }
1000
1001 private final class ServiceLookupResult {
1002 final ServiceRecord record;
1003 final String permission;
1004
1005 ServiceLookupResult(ServiceRecord _record, String _permission) {
1006 record = _record;
1007 permission = _permission;
1008 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001009 }
1010
1011 private class ServiceRestarter implements Runnable {
1012 private ServiceRecord mService;
1013
1014 void setService(ServiceRecord service) {
1015 mService = service;
1016 }
1017
1018 public void run() {
1019 synchronized(mAm) {
1020 performServiceRestartLocked(mService);
1021 }
1022 }
1023 }
1024
1025 private ServiceLookupResult retrieveServiceLocked(Intent service,
Svet Ganov99b60432015-06-27 13:15:22 -07001026 String resolvedType, String callingPackage, int callingPid, int callingUid, int userId,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001027 boolean createIfNeeded, boolean callingFromFg) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001028 ServiceRecord r = null;
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001029 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "retrieveServiceLocked: " + service
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001030 + " type=" + resolvedType + " callingUid=" + callingUid);
1031
Dianne Hackborn139748f2012-09-24 11:36:57 -07001032 userId = mAm.handleIncomingUser(callingPid, callingUid, userId,
Dianne Hackborn409297d2014-07-10 17:39:20 -07001033 false, ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE, "service", null);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001034
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001035 ServiceMap smap = getServiceMap(userId);
1036 final ComponentName comp = service.getComponent();
1037 if (comp != null) {
1038 r = smap.mServicesByName.get(comp);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001039 }
1040 if (r == null) {
1041 Intent.FilterComparison filter = new Intent.FilterComparison(service);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001042 r = smap.mServicesByIntent.get(filter);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001043 }
1044 if (r == null) {
1045 try {
1046 ResolveInfo rInfo =
1047 AppGlobals.getPackageManager().resolveService(
1048 service, resolvedType,
1049 ActivityManagerService.STOCK_PM_FLAGS, userId);
1050 ServiceInfo sInfo =
1051 rInfo != null ? rInfo.serviceInfo : null;
1052 if (sInfo == null) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001053 Slog.w(TAG_SERVICE, "Unable to start service " + service + " U=" + userId +
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001054 ": not found");
1055 return null;
1056 }
1057 ComponentName name = new ComponentName(
1058 sInfo.applicationInfo.packageName, sInfo.name);
1059 if (userId > 0) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -07001060 if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
Amith Yamasani4b9d79c2014-05-21 19:14:21 -07001061 sInfo.name, sInfo.flags)
1062 && mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001063 userId = 0;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001064 smap = getServiceMap(0);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001065 }
1066 sInfo = new ServiceInfo(sInfo);
1067 sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
1068 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001069 r = smap.mServicesByName.get(name);
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001070 if (r == null && createIfNeeded) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001071 Intent.FilterComparison filter
1072 = new Intent.FilterComparison(service.cloneFilter());
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001073 ServiceRestarter res = new ServiceRestarter();
1074 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
1075 BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics();
1076 synchronized (stats) {
1077 ss = stats.getServiceStatsLocked(
1078 sInfo.applicationInfo.uid, sInfo.packageName,
1079 sInfo.name);
1080 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001081 r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001082 res.setService(r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001083 smap.mServicesByName.put(name, r);
1084 smap.mServicesByIntent.put(filter, r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001085
1086 // Make sure this component isn't in the pending list.
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001087 for (int i=mPendingServices.size()-1; i>=0; i--) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001088 ServiceRecord pr = mPendingServices.get(i);
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001089 if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
1090 && pr.name.equals(name)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001091 mPendingServices.remove(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001092 }
1093 }
1094 }
1095 } catch (RemoteException ex) {
1096 // pm is in same process, this will never happen.
1097 }
1098 }
1099 if (r != null) {
1100 if (mAm.checkComponentPermission(r.permission,
1101 callingPid, callingUid, r.appInfo.uid, r.exported)
1102 != PackageManager.PERMISSION_GRANTED) {
1103 if (!r.exported) {
1104 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
1105 + " from pid=" + callingPid
1106 + ", uid=" + callingUid
1107 + " that is not exported from uid " + r.appInfo.uid);
1108 return new ServiceLookupResult(null, "not exported from uid "
1109 + r.appInfo.uid);
1110 }
1111 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
1112 + " from pid=" + callingPid
1113 + ", uid=" + callingUid
1114 + " requires " + r.permission);
1115 return new ServiceLookupResult(null, r.permission);
Svet Ganov99b60432015-06-27 13:15:22 -07001116 } else if (r.permission != null && callingPackage != null) {
1117 final int opCode = AppOpsManager.permissionToOpCode(r.permission);
1118 if (opCode != AppOpsManager.OP_NONE && mAm.mAppOpsService.noteOperation(
1119 opCode, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) {
1120 Slog.w(TAG, "Appop Denial: Accessing service " + r.name
1121 + " from pid=" + callingPid
1122 + ", uid=" + callingUid
1123 + " requires appop " + AppOpsManager.opToName(opCode));
1124 return null;
1125 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001126 }
Svet Ganov99b60432015-06-27 13:15:22 -07001127
Ben Gruverf5323fe2013-07-31 15:09:51 -07001128 if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
1129 resolvedType, r.appInfo)) {
Ben Gruverb6223792013-07-29 16:35:40 -07001130 return null;
1131 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001132 return new ServiceLookupResult(r, null);
1133 }
1134 return null;
1135 }
1136
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001137 private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001138 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, ">>> EXECUTING "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001139 + why + " of " + r + " in app " + r.app);
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001140 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING, ">>> EXECUTING "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001141 + why + " of " + r.shortName);
1142 long now = SystemClock.uptimeMillis();
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001143 if (r.executeNesting == 0) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001144 r.executeFg = fg;
Dianne Hackbornd2932242013-08-05 18:18:42 -07001145 ProcessStats.ServiceState stracker = r.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001146 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001147 stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001148 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001149 if (r.app != null) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001150 r.app.executingServices.add(r);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001151 r.app.execServicesFg |= fg;
Dianne Hackborn2be00932013-09-22 16:46:00 -07001152 if (r.app.executingServices.size() == 1) {
1153 scheduleServiceTimeoutLocked(r.app);
1154 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001155 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001156 } else if (r.app != null && fg && !r.app.execServicesFg) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001157 r.app.execServicesFg = true;
Dianne Hackborn2be00932013-09-22 16:46:00 -07001158 scheduleServiceTimeoutLocked(r.app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001159 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001160 r.executeFg |= fg;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001161 r.executeNesting++;
1162 r.executingStart = now;
1163 }
1164
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001165 private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
1166 boolean execInFg, boolean rebind) throws TransactionTooLargeException {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001167 if (r.app == null || r.app.thread == null) {
1168 // If service is not currently running, can't yet bind.
1169 return false;
1170 }
1171 if ((!i.requested || rebind) && i.apps.size() > 0) {
1172 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001173 bumpServiceExecutingLocked(r, execInFg, "bind");
Dianne Hackborna413dc02013-07-12 12:02:55 -07001174 r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
1175 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
1176 r.app.repProcState);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001177 if (!rebind) {
1178 i.requested = true;
1179 }
1180 i.hasBound = true;
1181 i.doRebind = false;
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001182 } catch (TransactionTooLargeException e) {
1183 // Keep the executeNesting count accurate.
1184 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r, e);
1185 final boolean inDestroying = mDestroyingServices.contains(r);
1186 serviceDoneExecutingLocked(r, inDestroying, inDestroying);
1187 throw e;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001188 } catch (RemoteException e) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001189 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r);
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001190 // Keep the executeNesting count accurate.
1191 final boolean inDestroying = mDestroyingServices.contains(r);
1192 serviceDoneExecutingLocked(r, inDestroying, inDestroying);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001193 return false;
1194 }
1195 }
1196 return true;
1197 }
1198
1199 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
1200 boolean allowCancel) {
1201 boolean canceled = false;
1202
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001203 ServiceMap smap = getServiceMap(r.userId);
1204 if (smap.mServicesByName.get(r.name) != r) {
1205 ServiceRecord cur = smap.mServicesByName.get(r.name);
1206 Slog.wtf(TAG, "Attempting to schedule restart of " + r
1207 + " when found in map: " + cur);
1208 return false;
1209 }
1210
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001211 final long now = SystemClock.uptimeMillis();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001212
1213 if ((r.serviceInfo.applicationInfo.flags
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001214 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
1215 long minDuration = SERVICE_RESTART_DURATION;
1216 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001217
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001218 // Any delivered but not yet finished starts should be put back
1219 // on the pending list.
1220 final int N = r.deliveredStarts.size();
1221 if (N > 0) {
1222 for (int i=N-1; i>=0; i--) {
1223 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
1224 si.removeUriPermissionsLocked();
1225 if (si.intent == null) {
1226 // We'll generate this again if needed.
1227 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
1228 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
1229 r.pendingStarts.add(0, si);
1230 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
1231 dur *= 2;
1232 if (minDuration < dur) minDuration = dur;
1233 if (resetTime < dur) resetTime = dur;
1234 } else {
1235 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
1236 + r.name);
1237 canceled = true;
1238 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001239 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001240 r.deliveredStarts.clear();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001241 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001242
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001243 r.totalRestartCount++;
1244 if (r.restartDelay == 0) {
1245 r.restartCount++;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001246 r.restartDelay = minDuration;
1247 } else {
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001248 // If it has been a "reasonably long time" since the service
1249 // was started, then reset our restart duration back to
1250 // the beginning, so we don't infinitely increase the duration
1251 // on a service that just occasionally gets killed (which is
1252 // a normal case, due to process being killed to reclaim memory).
1253 if (now > (r.restartTime+resetTime)) {
1254 r.restartCount = 1;
1255 r.restartDelay = minDuration;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001256 } else {
Dianne Hackborn7b492722013-11-01 09:58:45 -07001257 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
1258 if (r.restartDelay < minDuration) {
1259 r.restartDelay = minDuration;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001260 }
1261 }
1262 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001263
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001264 r.nextRestartTime = now + r.restartDelay;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001265
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001266 // Make sure that we don't end up restarting a bunch of services
1267 // all at the same time.
1268 boolean repeat;
1269 do {
1270 repeat = false;
1271 for (int i=mRestartingServices.size()-1; i>=0; i--) {
1272 ServiceRecord r2 = mRestartingServices.get(i);
1273 if (r2 != r && r.nextRestartTime
1274 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
1275 && r.nextRestartTime
1276 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
1277 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
1278 r.restartDelay = r.nextRestartTime - now;
1279 repeat = true;
1280 break;
1281 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001282 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001283 } while (repeat);
1284
1285 } else {
Dianne Hackborn7b492722013-11-01 09:58:45 -07001286 // Persistent processes are immediately restarted, so there is no
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001287 // reason to hold of on restarting their services.
1288 r.totalRestartCount++;
1289 r.restartCount = 0;
1290 r.restartDelay = 0;
1291 r.nextRestartTime = now;
1292 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001293
1294 if (!mRestartingServices.contains(r)) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001295 r.createdFromFg = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001296 mRestartingServices.add(r);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001297 r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001298 }
1299
1300 r.cancelNotification();
1301
1302 mAm.mHandler.removeCallbacks(r.restarter);
1303 mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime);
1304 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
1305 Slog.w(TAG, "Scheduling restart of crashed service "
1306 + r.shortName + " in " + r.restartDelay + "ms");
1307 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001308 r.userId, r.shortName, r.restartDelay);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001309
1310 return canceled;
1311 }
1312
1313 final void performServiceRestartLocked(ServiceRecord r) {
1314 if (!mRestartingServices.contains(r)) {
1315 return;
1316 }
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001317 try {
1318 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true);
1319 } catch (TransactionTooLargeException e) {
1320 // Ignore, it's been logged and nothing upstack cares.
1321 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001322 }
1323
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001324 private final boolean unscheduleServiceRestartLocked(ServiceRecord r, int callingUid,
1325 boolean force) {
1326 if (!force && r.restartDelay == 0) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001327 return false;
1328 }
Dianne Hackborn7b492722013-11-01 09:58:45 -07001329 // Remove from the restarting list; if the service is currently on the
1330 // restarting list, or the call is coming from another app, then this
1331 // service has become of much more interest so we reset the restart interval.
1332 boolean removed = mRestartingServices.remove(r);
1333 if (removed || callingUid != r.appInfo.uid) {
1334 r.resetRestartCounter();
1335 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001336 if (removed) {
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001337 clearRestartingIfNeededLocked(r);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001338 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001339 mAm.mHandler.removeCallbacks(r.restarter);
1340 return true;
1341 }
1342
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001343 private void clearRestartingIfNeededLocked(ServiceRecord r) {
1344 if (r.restartTracker != null) {
1345 // If this is the last restarting record with this tracker, then clear
1346 // the tracker's restarting state.
1347 boolean stillTracking = false;
1348 for (int i=mRestartingServices.size()-1; i>=0; i--) {
1349 if (mRestartingServices.get(i).restartTracker == r.restartTracker) {
1350 stillTracking = true;
1351 break;
1352 }
1353 }
1354 if (!stillTracking) {
1355 r.restartTracker.setRestarting(false, mAm.mProcessStats.getMemFactorLocked(),
1356 SystemClock.uptimeMillis());
1357 r.restartTracker = null;
1358 }
1359 }
1360 }
1361
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001362 private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
1363 boolean whileRestarting) throws TransactionTooLargeException {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001364 //Slog.i(TAG, "Bring up service:");
1365 //r.dump(" ");
1366
1367 if (r.app != null && r.app.thread != null) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001368 sendServiceArgsLocked(r, execInFg, false);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001369 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001370 }
1371
1372 if (!whileRestarting && r.restartDelay > 0) {
1373 // If waiting for a restart, then do nothing.
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001374 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001375 }
1376
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001377 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing up " + r + " " + r.intent);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001378
1379 // We are now bringing the service up, so no longer in the
1380 // restarting state.
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001381 if (mRestartingServices.remove(r)) {
chad7158ea22014-12-21 15:43:01 +08001382 r.resetRestartCounter();
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001383 clearRestartingIfNeededLocked(r);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001384 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001385
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001386 // Make sure this service is no longer considered delayed, we are starting it now.
1387 if (r.delayed) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001388 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (bring up): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001389 getServiceMap(r.userId).mDelayedStartList.remove(r);
1390 r.delayed = false;
1391 }
1392
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001393 // Make sure that the user who owns this service is started. If not,
1394 // we don't want to allow it to run.
1395 if (mAm.mStartedUsers.get(r.userId) == null) {
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001396 String msg = "Unable to launch app "
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001397 + r.appInfo.packageName + "/"
1398 + r.appInfo.uid + " for service "
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001399 + r.intent.getIntent() + ": user " + r.userId + " is stopped";
1400 Slog.w(TAG, msg);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001401 bringDownServiceLocked(r);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001402 return msg;
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001403 }
1404
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001405 // Service is now being launched, its package can't be stopped.
1406 try {
1407 AppGlobals.getPackageManager().setPackageStoppedState(
1408 r.packageName, false, r.userId);
1409 } catch (RemoteException e) {
1410 } catch (IllegalArgumentException e) {
1411 Slog.w(TAG, "Failed trying to unstop package "
1412 + r.packageName + ": " + e);
1413 }
1414
1415 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
1416 final String procName = r.processName;
1417 ProcessRecord app;
1418
1419 if (!isolated) {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001420 app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
1421 if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
1422 + " app=" + app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001423 if (app != null && app.thread != null) {
1424 try {
Dianne Hackbornf7097a52014-05-13 09:56:14 -07001425 app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001426 realStartServiceLocked(r, app, execInFg);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001427 return null;
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001428 } catch (TransactionTooLargeException e) {
1429 throw e;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001430 } catch (RemoteException e) {
1431 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
1432 }
1433
1434 // If a dead object exception was thrown -- fall through to
1435 // restart the application.
1436 }
1437 } else {
1438 // If this service runs in an isolated process, then each time
1439 // we call startProcessLocked() we will get a new isolated
1440 // process, starting another process if we are currently waiting
1441 // for a previous process to come up. To deal with this, we store
1442 // in the service any current isolated process it is running in or
1443 // waiting to have come up.
1444 app = r.isolatedProc;
1445 }
1446
1447 // Not running -- get it started, and enqueue this service record
1448 // to be executed when the app comes up.
1449 if (app == null) {
1450 if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001451 "service", r.name, false, isolated, false)) == null) {
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001452 String msg = "Unable to launch app "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001453 + r.appInfo.packageName + "/"
1454 + r.appInfo.uid + " for service "
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001455 + r.intent.getIntent() + ": process is bad";
1456 Slog.w(TAG, msg);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001457 bringDownServiceLocked(r);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001458 return msg;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001459 }
1460 if (isolated) {
1461 r.isolatedProc = app;
1462 }
1463 }
1464
1465 if (!mPendingServices.contains(r)) {
1466 mPendingServices.add(r);
1467 }
1468
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001469 if (r.delayedStop) {
1470 // Oh and hey we've already been asked to stop!
1471 r.delayedStop = false;
1472 if (r.startRequested) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001473 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
1474 "Applying delayed stop (in bring up): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001475 stopServiceLocked(r);
1476 }
1477 }
1478
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001479 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001480 }
1481
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001482 private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
1483 throws TransactionTooLargeException {
Dianne Hackborn390517b2013-05-30 15:03:32 -07001484 for (int i=r.bindings.size()-1; i>=0; i--) {
1485 IntentBindRecord ibr = r.bindings.valueAt(i);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001486 if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001487 break;
1488 }
1489 }
1490 }
1491
1492 private final void realStartServiceLocked(ServiceRecord r,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001493 ProcessRecord app, boolean execInFg) throws RemoteException {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001494 if (app.thread == null) {
1495 throw new RemoteException();
1496 }
1497 if (DEBUG_MU)
1498 Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
1499 + ", ProcessRecord.uid = " + app.uid);
1500 r.app = app;
1501 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
1502
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001503 final boolean newService = app.services.add(r);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001504 bumpServiceExecutingLocked(r, execInFg, "create");
Dianne Hackborndb926082013-10-31 16:32:44 -07001505 mAm.updateLruProcessLocked(app, false, null);
1506 mAm.updateOomAdjLocked();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001507
1508 boolean created = false;
1509 try {
Dianne Hackbornf85e7af2014-10-14 10:43:43 -07001510 if (LOG_SERVICE_START_STOP) {
Dianne Hackbornab2df062015-01-07 13:43:13 -08001511 String nameTerm;
1512 int lastPeriod = r.shortName.lastIndexOf('.');
1513 nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
Dianne Hackbornf85e7af2014-10-14 10:43:43 -07001514 EventLogTags.writeAmCreateService(
1515 r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
1516 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001517 synchronized (r.stats.getBatteryStats()) {
1518 r.stats.startLaunchedLocked();
1519 }
1520 mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
Dianne Hackborna413dc02013-07-12 12:02:55 -07001521 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001522 app.thread.scheduleCreateService(r, r.serviceInfo,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001523 mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
1524 app.repProcState);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001525 r.postNotification();
1526 created = true;
Craig Mautner4a8dddbf2014-08-13 10:49:26 -07001527 } catch (DeadObjectException e) {
1528 Slog.w(TAG, "Application dead when creating service " + r);
1529 mAm.appDiedLocked(app);
Wale Ogunwalebfac4682015-04-08 14:33:21 -07001530 throw e;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001531 } finally {
1532 if (!created) {
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001533 // Keep the executeNesting count accurate.
1534 final boolean inDestroying = mDestroyingServices.contains(r);
1535 serviceDoneExecutingLocked(r, inDestroying, inDestroying);
1536
1537 // Cleanup.
1538 if (newService) {
1539 app.services.remove(r);
1540 r.app = null;
1541 }
1542
1543 // Retry.
1544 if (!inDestroying) {
1545 scheduleServiceRestartLocked(r, false);
1546 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001547 }
1548 }
1549
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001550 requestServiceBindingsLocked(r, execInFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001551
Dianne Hackborn465fa392014-09-14 14:21:18 -07001552 updateServiceClientActivitiesLocked(app, null, true);
1553
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001554 // If the service is in the started state, and there are no
1555 // pending arguments, then fake up one so its onStartCommand() will
1556 // be called.
1557 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
1558 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
1559 null, null));
1560 }
1561
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001562 sendServiceArgsLocked(r, execInFg, true);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001563
1564 if (r.delayed) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001565 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001566 getServiceMap(r.userId).mDelayedStartList.remove(r);
1567 r.delayed = false;
1568 }
1569
1570 if (r.delayedStop) {
1571 // Oh and hey we've already been asked to stop!
1572 r.delayedStop = false;
1573 if (r.startRequested) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001574 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
1575 "Applying delayed stop (from start): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001576 stopServiceLocked(r);
1577 }
1578 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001579 }
1580
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001581 private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001582 boolean oomAdjusted) throws TransactionTooLargeException {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001583 final int N = r.pendingStarts.size();
1584 if (N == 0) {
1585 return;
1586 }
1587
1588 while (r.pendingStarts.size() > 0) {
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001589 Exception caughtException = null;
1590 ServiceRecord.StartItem si;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001591 try {
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001592 si = r.pendingStarts.remove(0);
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001593 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Sending arguments to: "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001594 + r + " " + r.intent + " args=" + si.intent);
1595 if (si.intent == null && N > 1) {
1596 // If somehow we got a dummy null intent in the middle,
1597 // then skip it. DO NOT skip a null intent when it is
1598 // the only one in the list -- this is to support the
1599 // onStartCommand(null) case.
1600 continue;
1601 }
1602 si.deliveredTime = SystemClock.uptimeMillis();
1603 r.deliveredStarts.add(si);
1604 si.deliveryCount++;
1605 if (si.neededGrants != null) {
1606 mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
1607 si.getUriPermissionsLocked());
1608 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001609 bumpServiceExecutingLocked(r, execInFg, "start");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001610 if (!oomAdjusted) {
1611 oomAdjusted = true;
1612 mAm.updateOomAdjLocked(r.app);
1613 }
1614 int flags = 0;
1615 if (si.deliveryCount > 1) {
1616 flags |= Service.START_FLAG_RETRY;
1617 }
1618 if (si.doneExecutingCount > 0) {
1619 flags |= Service.START_FLAG_REDELIVERY;
1620 }
1621 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001622 } catch (TransactionTooLargeException e) {
1623 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Transaction too large: intent="
1624 + si.intent);
1625 caughtException = e;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001626 } catch (RemoteException e) {
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001627 // Remote process gone... we'll let the normal cleanup take care of this.
1628 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while sending args: " + r);
1629 caughtException = e;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001630 } catch (Exception e) {
1631 Slog.w(TAG, "Unexpected exception", e);
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001632 caughtException = e;
1633 }
1634
1635 if (caughtException != null) {
1636 // Keep nesting count correct
1637 final boolean inDestroying = mDestroyingServices.contains(r);
1638 serviceDoneExecutingLocked(r, inDestroying, inDestroying);
1639 if (caughtException instanceof TransactionTooLargeException) {
1640 throw (TransactionTooLargeException)caughtException;
1641 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001642 break;
1643 }
1644 }
1645 }
1646
Dianne Hackborn164371f2013-10-01 19:10:13 -07001647 private final boolean isServiceNeeded(ServiceRecord r, boolean knowConn, boolean hasConn) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001648 // Are we still explicitly being asked to run?
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001649 if (r.startRequested) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001650 return true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001651 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001652
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001653 // Is someone still bound to us keepign us running?
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001654 if (!knowConn) {
1655 hasConn = r.hasAutoCreateConnections();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001656 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001657 if (hasConn) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001658 return true;
1659 }
1660
1661 return false;
1662 }
1663
1664 private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
1665 boolean hasConn) {
1666 //Slog.i(TAG, "Bring down service:");
1667 //r.dump(" ");
1668
1669 if (isServiceNeeded(r, knowConn, hasConn)) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001670 return;
1671 }
1672
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001673 // Are we in the process of launching?
1674 if (mPendingServices.contains(r)) {
1675 return;
1676 }
1677
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001678 bringDownServiceLocked(r);
1679 }
1680
1681 private final void bringDownServiceLocked(ServiceRecord r) {
1682 //Slog.i(TAG, "Bring down service:");
1683 //r.dump(" ");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001684
Dianne Hackborn390517b2013-05-30 15:03:32 -07001685 // Report to all of the connections that the service is no longer
1686 // available.
1687 for (int conni=r.connections.size()-1; conni>=0; conni--) {
1688 ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
1689 for (int i=0; i<c.size(); i++) {
1690 ConnectionRecord cr = c.get(i);
1691 // There is still a connection to the service that is
1692 // being brought down. Mark it as dead.
1693 cr.serviceDead = true;
1694 try {
1695 cr.conn.connected(r.name, null);
1696 } catch (Exception e) {
1697 Slog.w(TAG, "Failure disconnecting service " + r.name +
1698 " to connection " + c.get(i).conn.asBinder() +
1699 " (in " + c.get(i).binding.client.processName + ")", e);
1700 }
1701 }
1702 }
1703
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001704 // Tell the service that it has been unbound.
Dianne Hackborn390517b2013-05-30 15:03:32 -07001705 if (r.app != null && r.app.thread != null) {
1706 for (int i=r.bindings.size()-1; i>=0; i--) {
1707 IntentBindRecord ibr = r.bindings.valueAt(i);
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001708 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing down binding " + ibr
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001709 + ": hasBound=" + ibr.hasBound);
Dianne Hackborn390517b2013-05-30 15:03:32 -07001710 if (ibr.hasBound) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001711 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001712 bumpServiceExecutingLocked(r, false, "bring down unbind");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001713 mAm.updateOomAdjLocked(r.app);
1714 ibr.hasBound = false;
1715 r.app.thread.scheduleUnbindService(r,
1716 ibr.intent.getIntent());
1717 } catch (Exception e) {
1718 Slog.w(TAG, "Exception when unbinding service "
1719 + r.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001720 serviceProcessGoneLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001721 }
1722 }
1723 }
1724 }
1725
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001726 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing down " + r + " " + r.intent);
Craig Mautner66c4a822015-01-16 12:48:16 -08001727 r.destroyTime = SystemClock.uptimeMillis();
Dianne Hackbornf85e7af2014-10-14 10:43:43 -07001728 if (LOG_SERVICE_START_STOP) {
1729 EventLogTags.writeAmDestroyService(
1730 r.userId, System.identityHashCode(r), (r.app != null) ? r.app.pid : -1);
1731 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001732
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001733 final ServiceMap smap = getServiceMap(r.userId);
1734 smap.mServicesByName.remove(r.name);
1735 smap.mServicesByIntent.remove(r.intent);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001736 r.totalRestartCount = 0;
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001737 unscheduleServiceRestartLocked(r, 0, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001738
1739 // Also make sure it is not on the pending list.
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001740 for (int i=mPendingServices.size()-1; i>=0; i--) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001741 if (mPendingServices.get(i) == r) {
1742 mPendingServices.remove(i);
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001743 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Removed pending: " + r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001744 }
1745 }
1746
1747 r.cancelNotification();
1748 r.isForeground = false;
1749 r.foregroundId = 0;
1750 r.foregroundNoti = null;
1751
1752 // Clear start entries.
1753 r.clearDeliveredStartsLocked();
1754 r.pendingStarts.clear();
1755
1756 if (r.app != null) {
1757 synchronized (r.stats.getBatteryStats()) {
1758 r.stats.stopLaunchedLocked();
1759 }
1760 r.app.services.remove(r);
1761 if (r.app.thread != null) {
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001762 updateServiceForegroundLocked(r.app, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001763 try {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001764 bumpServiceExecutingLocked(r, false, "destroy");
1765 mDestroyingServices.add(r);
Dianne Hackborn455625e2015-01-21 09:55:13 -08001766 r.destroying = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001767 mAm.updateOomAdjLocked(r.app);
1768 r.app.thread.scheduleStopService(r);
1769 } catch (Exception e) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001770 Slog.w(TAG, "Exception when destroying service "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001771 + r.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001772 serviceProcessGoneLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001773 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001774 } else {
1775 if (DEBUG_SERVICE) Slog.v(
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001776 TAG_SERVICE, "Removed service that has no process: " + r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001777 }
1778 } else {
1779 if (DEBUG_SERVICE) Slog.v(
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001780 TAG_SERVICE, "Removed service that is not running: " + r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001781 }
1782
1783 if (r.bindings.size() > 0) {
1784 r.bindings.clear();
1785 }
1786
1787 if (r.restarter instanceof ServiceRestarter) {
1788 ((ServiceRestarter)r.restarter).setService(null);
1789 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001790
Dianne Hackbornd2932242013-08-05 18:18:42 -07001791 int memFactor = mAm.mProcessStats.getMemFactorLocked();
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001792 long now = SystemClock.uptimeMillis();
1793 if (r.tracker != null) {
1794 r.tracker.setStarted(false, memFactor, now);
1795 r.tracker.setBound(false, memFactor, now);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001796 if (r.executeNesting == 0) {
Dianne Hackborn878deb32013-10-14 16:55:09 -07001797 r.tracker.clearCurrentOwner(r, false);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001798 r.tracker = null;
1799 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001800 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001801
1802 smap.ensureNotStartingBackground(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001803 }
1804
1805 void removeConnectionLocked(
1806 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
1807 IBinder binder = c.conn.asBinder();
1808 AppBindRecord b = c.binding;
1809 ServiceRecord s = b.service;
1810 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
1811 if (clist != null) {
1812 clist.remove(c);
1813 if (clist.size() == 0) {
1814 s.connections.remove(binder);
1815 }
1816 }
1817 b.connections.remove(c);
1818 if (c.activity != null && c.activity != skipAct) {
1819 if (c.activity.connections != null) {
1820 c.activity.connections.remove(c);
1821 }
1822 }
1823 if (b.client != skipApp) {
1824 b.client.connections.remove(c);
1825 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
1826 b.client.updateHasAboveClientLocked();
1827 }
Dianne Hackborndb926082013-10-31 16:32:44 -07001828 if (s.app != null) {
Dianne Hackborn465fa392014-09-14 14:21:18 -07001829 updateServiceClientActivitiesLocked(s.app, c, true);
Dianne Hackborndb926082013-10-31 16:32:44 -07001830 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001831 }
1832 clist = mServiceConnections.get(binder);
1833 if (clist != null) {
1834 clist.remove(c);
1835 if (clist.size() == 0) {
1836 mServiceConnections.remove(binder);
1837 }
1838 }
1839
Dianne Hackbornab2df062015-01-07 13:43:13 -08001840 mAm.stopAssociationLocked(b.client.uid, b.client.processName, s.appInfo.uid, s.name);
1841
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001842 if (b.connections.size() == 0) {
1843 b.intent.apps.remove(b.client);
1844 }
1845
1846 if (!c.serviceDead) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001847 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Disconnecting binding " + b.intent
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001848 + ": shouldUnbind=" + b.intent.hasBound);
1849 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
1850 && b.intent.hasBound) {
1851 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001852 bumpServiceExecutingLocked(s, false, "unbind");
Dianne Hackborndb926082013-10-31 16:32:44 -07001853 if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0
1854 && s.app.setProcState <= ActivityManager.PROCESS_STATE_RECEIVER) {
1855 // If this service's process is not already in the cached list,
1856 // then update it in the LRU list here because this may be causing
1857 // it to go down there and we want it to start out near the top.
1858 mAm.updateLruProcessLocked(s.app, false, null);
1859 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001860 mAm.updateOomAdjLocked(s.app);
1861 b.intent.hasBound = false;
1862 // Assume the client doesn't want to know about a rebind;
1863 // we will deal with that later if it asks for one.
1864 b.intent.doRebind = false;
1865 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
1866 } catch (Exception e) {
1867 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001868 serviceProcessGoneLocked(s);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001869 }
1870 }
1871
1872 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001873 boolean hasAutoCreate = s.hasAutoCreateConnections();
1874 if (!hasAutoCreate) {
1875 if (s.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001876 s.tracker.setBound(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001877 SystemClock.uptimeMillis());
1878 }
1879 }
1880 bringDownServiceIfNeededLocked(s, true, hasAutoCreate);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001881 }
1882 }
1883 }
1884
1885 void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001886 boolean inDestroying = mDestroyingServices.contains(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001887 if (r != null) {
Dianne Hackborn455625e2015-01-21 09:55:13 -08001888 if (type == ActivityThread.SERVICE_DONE_EXECUTING_START) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001889 // This is a call from a service start... take care of
1890 // book-keeping.
1891 r.callStart = true;
1892 switch (res) {
1893 case Service.START_STICKY_COMPATIBILITY:
1894 case Service.START_STICKY: {
1895 // We are done with the associated start arguments.
1896 r.findDeliveredStart(startId, true);
1897 // Don't stop if killed.
1898 r.stopIfKilled = false;
1899 break;
1900 }
1901 case Service.START_NOT_STICKY: {
1902 // We are done with the associated start arguments.
1903 r.findDeliveredStart(startId, true);
1904 if (r.getLastStartId() == startId) {
1905 // There is no more work, and this service
1906 // doesn't want to hang around if killed.
1907 r.stopIfKilled = true;
1908 }
1909 break;
1910 }
1911 case Service.START_REDELIVER_INTENT: {
1912 // We'll keep this item until they explicitly
1913 // call stop for it, but keep track of the fact
1914 // that it was delivered.
1915 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
1916 if (si != null) {
1917 si.deliveryCount = 0;
1918 si.doneExecutingCount++;
1919 // Don't stop if killed.
1920 r.stopIfKilled = true;
1921 }
1922 break;
1923 }
1924 case Service.START_TASK_REMOVED_COMPLETE: {
1925 // Special processing for onTaskRemoved(). Don't
1926 // impact normal onStartCommand() processing.
1927 r.findDeliveredStart(startId, true);
1928 break;
1929 }
1930 default:
1931 throw new IllegalArgumentException(
1932 "Unknown service start result: " + res);
1933 }
1934 if (res == Service.START_STICKY_COMPATIBILITY) {
1935 r.callStart = false;
1936 }
Dianne Hackborn455625e2015-01-21 09:55:13 -08001937 } else if (type == ActivityThread.SERVICE_DONE_EXECUTING_STOP) {
1938 // This is the final call from destroying the service... we should
1939 // actually be getting rid of the service at this point. Do some
1940 // validation of its state, and ensure it will be fully removed.
1941 if (!inDestroying) {
1942 // Not sure what else to do with this... if it is not actually in the
1943 // destroying list, we don't need to make sure to remove it from it.
1944 Slog.wtfStack(TAG, "Service done with onDestroy, but not inDestroying: "
1945 + r);
1946 } else if (r.executeNesting != 1) {
1947 Slog.wtfStack(TAG, "Service done with onDestroy, but executeNesting="
1948 + r.executeNesting + ": " + r);
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001949 // Fake it to keep from ANR due to orphaned entry.
Dianne Hackborn455625e2015-01-21 09:55:13 -08001950 r.executeNesting = 1;
1951 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001952 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001953 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn164371f2013-10-01 19:10:13 -07001954 serviceDoneExecutingLocked(r, inDestroying, inDestroying);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001955 Binder.restoreCallingIdentity(origId);
1956 } else {
1957 Slog.w(TAG, "Done executing unknown service from pid "
1958 + Binder.getCallingPid());
1959 }
1960 }
1961
Dianne Hackborn878deb32013-10-14 16:55:09 -07001962 private void serviceProcessGoneLocked(ServiceRecord r) {
1963 if (r.tracker != null) {
1964 int memFactor = mAm.mProcessStats.getMemFactorLocked();
1965 long now = SystemClock.uptimeMillis();
1966 r.tracker.setExecuting(false, memFactor, now);
1967 r.tracker.setBound(false, memFactor, now);
Dianne Hackbornbc72dce2013-11-11 10:43:38 -08001968 r.tracker.setStarted(false, memFactor, now);
Dianne Hackborn878deb32013-10-14 16:55:09 -07001969 }
1970 serviceDoneExecutingLocked(r, true, true);
1971 }
1972
Dianne Hackborn164371f2013-10-01 19:10:13 -07001973 private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
1974 boolean finishing) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001975 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "<<< DONE EXECUTING " + r
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001976 + ": nesting=" + r.executeNesting
Dianne Hackborn164371f2013-10-01 19:10:13 -07001977 + ", inDestroying=" + inDestroying + ", app=" + r.app);
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001978 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,
1979 "<<< DONE EXECUTING " + r.shortName);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001980 r.executeNesting--;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001981 if (r.executeNesting <= 0) {
1982 if (r.app != null) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001983 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001984 "Nesting at 0 of " + r.shortName);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001985 r.app.execServicesFg = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001986 r.app.executingServices.remove(r);
1987 if (r.app.executingServices.size() == 0) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001988 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001989 "No more executingServices of " + r.shortName);
1990 mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001991 } else if (r.executeFg) {
1992 // Need to re-evaluate whether the app still needs to be in the foreground.
1993 for (int i=r.app.executingServices.size()-1; i>=0; i--) {
1994 if (r.app.executingServices.valueAt(i).executeFg) {
1995 r.app.execServicesFg = true;
1996 break;
1997 }
1998 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001999 }
Dianne Hackborn164371f2013-10-01 19:10:13 -07002000 if (inDestroying) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002001 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
Dianne Hackborn164371f2013-10-01 19:10:13 -07002002 "doneExecuting remove destroying " + r);
2003 mDestroyingServices.remove(r);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002004 r.bindings.clear();
2005 }
2006 mAm.updateOomAdjLocked(r.app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002007 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002008 r.executeFg = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002009 if (r.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07002010 r.tracker.setExecuting(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002011 SystemClock.uptimeMillis());
Dianne Hackborn164371f2013-10-01 19:10:13 -07002012 if (finishing) {
Dianne Hackborn878deb32013-10-14 16:55:09 -07002013 r.tracker.clearCurrentOwner(r, false);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07002014 r.tracker = null;
2015 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002016 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002017 if (finishing) {
Dianne Hackborn90e9b1d2013-11-21 12:50:01 -08002018 if (r.app != null && !r.app.persistent) {
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002019 r.app.services.remove(r);
2020 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002021 r.app = null;
2022 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002023 }
2024 }
2025
Dianne Hackbornff072722014-09-24 10:56:28 -07002026 boolean attachApplicationLocked(ProcessRecord proc, String processName)
2027 throws RemoteException {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002028 boolean didSomething = false;
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07002029 // Collect any services that are waiting for this process to come up.
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002030 if (mPendingServices.size() > 0) {
2031 ServiceRecord sr = null;
2032 try {
2033 for (int i=0; i<mPendingServices.size(); i++) {
2034 sr = mPendingServices.get(i);
2035 if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
2036 || !processName.equals(sr.processName))) {
2037 continue;
2038 }
2039
2040 mPendingServices.remove(i);
2041 i--;
Dianne Hackbornf7097a52014-05-13 09:56:14 -07002042 proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,
2043 mAm.mProcessStats);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002044 realStartServiceLocked(sr, proc, sr.createdFromFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002045 didSomething = true;
2046 }
Dianne Hackbornff072722014-09-24 10:56:28 -07002047 } catch (RemoteException e) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002048 Slog.w(TAG, "Exception in new application when starting service "
2049 + sr.shortName, e);
2050 throw e;
2051 }
2052 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07002053 // Also, if there are any services that are waiting to restart and
2054 // would run in this process, now is a good time to start them. It would
2055 // be weird to bring up the process but arbitrarily not let the services
2056 // run at this point just because their restart time hasn't come up.
2057 if (mRestartingServices.size() > 0) {
2058 ServiceRecord sr = null;
2059 for (int i=0; i<mRestartingServices.size(); i++) {
2060 sr = mRestartingServices.get(i);
2061 if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
2062 || !processName.equals(sr.processName))) {
2063 continue;
2064 }
2065 mAm.mHandler.removeCallbacks(sr.restarter);
2066 mAm.mHandler.post(sr.restarter);
2067 }
2068 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002069 return didSomething;
2070 }
2071
2072 void processStartTimedOutLocked(ProcessRecord proc) {
2073 for (int i=0; i<mPendingServices.size(); i++) {
2074 ServiceRecord sr = mPendingServices.get(i);
2075 if ((proc.uid == sr.appInfo.uid
2076 && proc.processName.equals(sr.processName))
2077 || sr.isolatedProc == proc) {
2078 Slog.w(TAG, "Forcing bringing down service: " + sr);
2079 sr.isolatedProc = null;
2080 mPendingServices.remove(i);
2081 i--;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002082 bringDownServiceLocked(sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002083 }
2084 }
2085 }
2086
Wale Ogunwale540e1232015-05-01 15:35:39 -07002087 private boolean collectPackageServicesLocked(String packageName, Set<String> filterByClasses,
Wale Ogunwale2cb2dd42015-09-02 14:53:29 -07002088 boolean evenPersistent, boolean doit, boolean killProcess,
2089 ArrayMap<ComponentName, ServiceRecord> services) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002090 boolean didSomething = false;
Wale Ogunwale540e1232015-05-01 15:35:39 -07002091 for (int i = services.size() - 1; i >= 0; i--) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002092 ServiceRecord service = services.valueAt(i);
Wale Ogunwale540e1232015-05-01 15:35:39 -07002093 final boolean sameComponent = packageName == null
2094 || (service.packageName.equals(packageName)
2095 && (filterByClasses == null
2096 || filterByClasses.contains(service.name.getClassName())));
2097 if (sameComponent
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002098 && (service.app == null || evenPersistent || !service.app.persistent)) {
2099 if (!doit) {
2100 return true;
2101 }
2102 didSomething = true;
2103 Slog.i(TAG, " Force stopping service " + service);
2104 if (service.app != null) {
Wale Ogunwale2cb2dd42015-09-02 14:53:29 -07002105 service.app.removed = killProcess;
Dianne Hackborn90e9b1d2013-11-21 12:50:01 -08002106 if (!service.app.persistent) {
2107 service.app.services.remove(service);
2108 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002109 }
2110 service.app = null;
2111 service.isolatedProc = null;
Wale Ogunwale540e1232015-05-01 15:35:39 -07002112 if (mTmpCollectionResults == null) {
2113 mTmpCollectionResults = new ArrayList<>();
2114 }
2115 mTmpCollectionResults.add(service);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002116 }
2117 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07002118 return didSomething;
2119 }
2120
Wale Ogunwale540e1232015-05-01 15:35:39 -07002121 boolean bringDownDisabledPackageServicesLocked(String packageName, Set<String> filterByClasses,
Wale Ogunwale2cb2dd42015-09-02 14:53:29 -07002122 int userId, boolean evenPersistent, boolean killProcess, boolean doit) {
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07002123 boolean didSomething = false;
Wale Ogunwale540e1232015-05-01 15:35:39 -07002124
2125 if (mTmpCollectionResults != null) {
2126 mTmpCollectionResults.clear();
2127 }
2128
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07002129 if (userId == UserHandle.USER_ALL) {
Wale Ogunwale540e1232015-05-01 15:35:39 -07002130 for (int i = mServiceMap.size() - 1; i >= 0; i--) {
2131 didSomething |= collectPackageServicesLocked(packageName, filterByClasses,
Wale Ogunwale2cb2dd42015-09-02 14:53:29 -07002132 evenPersistent, doit, killProcess, mServiceMap.valueAt(i).mServicesByName);
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07002133 if (!doit && didSomething) {
2134 return true;
2135 }
2136 }
2137 } else {
Amith Yamasani540b6592013-10-01 13:02:52 -07002138 ServiceMap smap = mServiceMap.get(userId);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002139 if (smap != null) {
2140 ArrayMap<ComponentName, ServiceRecord> items = smap.mServicesByName;
Wale Ogunwale540e1232015-05-01 15:35:39 -07002141 didSomething = collectPackageServicesLocked(packageName, filterByClasses,
Wale Ogunwale2cb2dd42015-09-02 14:53:29 -07002142 evenPersistent, doit, killProcess, items);
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07002143 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07002144 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002145
Wale Ogunwale540e1232015-05-01 15:35:39 -07002146 if (mTmpCollectionResults != null) {
2147 for (int i = mTmpCollectionResults.size() - 1; i >= 0; i--) {
2148 bringDownServiceLocked(mTmpCollectionResults.get(i));
2149 }
2150 mTmpCollectionResults.clear();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002151 }
2152 return didSomething;
2153 }
2154
2155 void cleanUpRemovedTaskLocked(TaskRecord tr, ComponentName component, Intent baseIntent) {
Wale Ogunwale540e1232015-05-01 15:35:39 -07002156 ArrayList<ServiceRecord> services = new ArrayList<>();
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002157 ArrayMap<ComponentName, ServiceRecord> alls = getServices(tr.userId);
Wale Ogunwale540e1232015-05-01 15:35:39 -07002158 for (int i = alls.size() - 1; i >= 0; i--) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002159 ServiceRecord sr = alls.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002160 if (sr.packageName.equals(component.getPackageName())) {
2161 services.add(sr);
2162 }
2163 }
2164
2165 // Take care of any running services associated with the app.
Wale Ogunwale540e1232015-05-01 15:35:39 -07002166 for (int i = services.size() - 1; i >= 0; i--) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002167 ServiceRecord sr = services.get(i);
2168 if (sr.startRequested) {
2169 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
2170 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
2171 stopServiceLocked(sr);
2172 } else {
2173 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
2174 sr.makeNextStartId(), baseIntent, null));
2175 if (sr.app != null && sr.app.thread != null) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002176 // We always run in the foreground, since this is called as
2177 // part of the "remove task" UI operation.
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07002178 try {
2179 sendServiceArgsLocked(sr, true, false);
2180 } catch (TransactionTooLargeException e) {
2181 // Ignore, keep going.
2182 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002183 }
2184 }
2185 }
2186 }
2187 }
2188
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002189 final void killServicesLocked(ProcessRecord app, boolean allowRestart) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002190 // Report disconnected services.
2191 if (false) {
2192 // XXX we are letting the client link to the service for
2193 // death notifications.
2194 if (app.services.size() > 0) {
2195 Iterator<ServiceRecord> it = app.services.iterator();
2196 while (it.hasNext()) {
2197 ServiceRecord r = it.next();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002198 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2199 ArrayList<ConnectionRecord> cl = r.connections.valueAt(conni);
2200 for (int i=0; i<cl.size(); i++) {
2201 ConnectionRecord c = cl.get(i);
2202 if (c.binding.client != app) {
2203 try {
2204 //c.conn.connected(r.className, null);
2205 } catch (Exception e) {
2206 // todo: this should be asynchronous!
2207 Slog.w(TAG, "Exception thrown disconnected servce "
2208 + r.shortName
2209 + " from app " + app.processName, e);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002210 }
2211 }
2212 }
2213 }
2214 }
2215 }
2216 }
2217
louis_chang40e259c2015-03-26 13:31:14 +08002218 // Clean up any connections this application has to other services.
2219 for (int i = app.connections.size() - 1; i >= 0; i--) {
2220 ConnectionRecord r = app.connections.valueAt(i);
2221 removeConnectionLocked(r, app, null);
2222 }
2223 updateServiceConnectionActivitiesLocked(app);
2224 app.connections.clear();
2225
2226 // Clear app state from services.
2227 for (int i = app.services.size() - 1; i >= 0; i--) {
Dianne Hackbornc8230512013-07-13 21:32:12 -07002228 ServiceRecord sr = app.services.valueAt(i);
2229 synchronized (sr.stats.getBatteryStats()) {
2230 sr.stats.stopLaunchedLocked();
2231 }
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08002232 if (sr.app != app && sr.app != null && !sr.app.persistent) {
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002233 sr.app.services.remove(sr);
2234 }
Dianne Hackbornc8230512013-07-13 21:32:12 -07002235 sr.app = null;
2236 sr.isolatedProc = null;
2237 sr.executeNesting = 0;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002238 sr.forceClearTracker();
2239 if (mDestroyingServices.remove(sr)) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002240 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "killServices remove destroying " + sr);
Dianne Hackbornc8230512013-07-13 21:32:12 -07002241 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002242
Dianne Hackbornc8230512013-07-13 21:32:12 -07002243 final int numClients = sr.bindings.size();
2244 for (int bindingi=numClients-1; bindingi>=0; bindingi--) {
2245 IntentBindRecord b = sr.bindings.valueAt(bindingi);
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002246 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Killing binding " + b
Dianne Hackbornc8230512013-07-13 21:32:12 -07002247 + ": shouldUnbind=" + b.hasBound);
2248 b.binder = null;
2249 b.requested = b.received = b.hasBound = false;
Dianne Hackborn465fa392014-09-14 14:21:18 -07002250 // If this binding is coming from a cached process and is asking to keep
2251 // the service created, then we'll kill the cached process as well -- we
2252 // don't want to be thrashing around restarting processes that are only
2253 // there to be cached.
2254 for (int appi=b.apps.size()-1; appi>=0; appi--) {
Dianne Hackborn24c98e82014-09-14 17:23:54 -07002255 final ProcessRecord proc = b.apps.keyAt(appi);
2256 // If the process is already gone, skip it.
2257 if (proc.killedByAm || proc.thread == null) {
2258 continue;
2259 }
2260 // Only do this for processes that have an auto-create binding;
2261 // otherwise the binding can be left, because it won't cause the
2262 // service to restart.
2263 final AppBindRecord abind = b.apps.valueAt(appi);
2264 boolean hasCreate = false;
2265 for (int conni=abind.connections.size()-1; conni>=0; conni--) {
2266 ConnectionRecord conn = abind.connections.valueAt(conni);
Dianne Hackborn0fe3c252014-09-19 15:09:39 -07002267 if ((conn.flags&(Context.BIND_AUTO_CREATE|Context.BIND_ALLOW_OOM_MANAGEMENT
2268 |Context.BIND_WAIVE_PRIORITY)) == Context.BIND_AUTO_CREATE) {
Dianne Hackborn24c98e82014-09-14 17:23:54 -07002269 hasCreate = true;
2270 break;
2271 }
2272 }
2273 if (!hasCreate) {
2274 continue;
2275 }
Dianne Hackborncd97c962014-09-25 18:34:02 -07002276 // XXX turned off for now until we have more time to get a better policy.
2277 if (false && proc != null && !proc.persistent && proc.thread != null
Dianne Hackborn465fa392014-09-14 14:21:18 -07002278 && proc.pid != 0 && proc.pid != ActivityManagerService.MY_PID
2279 && proc.setProcState >= ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
2280 proc.kill("bound to service " + sr.name.flattenToShortString()
2281 + " in dying proc " + (app != null ? app.processName : "??"), true);
2282 }
2283 }
Dianne Hackbornc8230512013-07-13 21:32:12 -07002284 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002285 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002286
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002287 ServiceMap smap = getServiceMap(app.userId);
2288
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002289 // Now do remaining service cleanup.
2290 for (int i=app.services.size()-1; i>=0; i--) {
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002291 ServiceRecord sr = app.services.valueAt(i);
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08002292
2293 // Unless the process is persistent, this process record is going away,
2294 // so make sure the service is cleaned out of it.
2295 if (!app.persistent) {
Dianne Hackborn4190fc52013-12-09 18:20:16 -08002296 app.services.removeAt(i);
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08002297 }
2298
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002299 // Sanity check: if the service listed for the app is not one
Dianne Hackborn4190fc52013-12-09 18:20:16 -08002300 // we actually are maintaining, just let it drop.
Dianne Hackborn40c87252014-03-19 16:55:40 -07002301 final ServiceRecord curRec = smap.mServicesByName.get(sr.name);
2302 if (curRec != sr) {
2303 if (curRec != null) {
2304 Slog.wtf(TAG, "Service " + sr + " in process " + app
2305 + " not same as in map: " + curRec);
2306 }
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002307 continue;
2308 }
2309
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002310 // Any services running in the application may need to be placed
2311 // back in the pending list.
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002312 if (allowRestart && sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
Dianne Hackbornc8230512013-07-13 21:32:12 -07002313 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
2314 Slog.w(TAG, "Service crashed " + sr.crashCount
2315 + " times, stopping: " + sr);
2316 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
2317 sr.userId, sr.crashCount, sr.shortName, app.pid);
2318 bringDownServiceLocked(sr);
younghwan1.kimcd005eb2015-04-02 19:15:11 +09002319 } else if (!allowRestart || !mAm.isUserRunningLocked(sr.userId, false)) {
Dianne Hackbornc8230512013-07-13 21:32:12 -07002320 bringDownServiceLocked(sr);
2321 } else {
2322 boolean canceled = scheduleServiceRestartLocked(sr, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002323
Dianne Hackbornc8230512013-07-13 21:32:12 -07002324 // Should the service remain running? Note that in the
2325 // extreme case of so many attempts to deliver a command
2326 // that it failed we also will stop it here.
2327 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
2328 if (sr.pendingStarts.size() == 0) {
2329 sr.startRequested = false;
2330 if (sr.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07002331 sr.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackbornc8230512013-07-13 21:32:12 -07002332 SystemClock.uptimeMillis());
2333 }
2334 if (!sr.hasAutoCreateConnections()) {
2335 // Whoops, no reason to restart!
2336 bringDownServiceLocked(sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002337 }
2338 }
2339 }
2340 }
Dianne Hackbornc8230512013-07-13 21:32:12 -07002341 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002342
Dianne Hackbornc8230512013-07-13 21:32:12 -07002343 if (!allowRestart) {
2344 app.services.clear();
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002345
2346 // Make sure there are no more restarting services for this process.
2347 for (int i=mRestartingServices.size()-1; i>=0; i--) {
2348 ServiceRecord r = mRestartingServices.get(i);
2349 if (r.processName.equals(app.processName) &&
2350 r.serviceInfo.applicationInfo.uid == app.info.uid) {
2351 mRestartingServices.remove(i);
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08002352 clearRestartingIfNeededLocked(r);
2353 }
2354 }
2355 for (int i=mPendingServices.size()-1; i>=0; i--) {
2356 ServiceRecord r = mPendingServices.get(i);
2357 if (r.processName.equals(app.processName) &&
2358 r.serviceInfo.applicationInfo.uid == app.info.uid) {
2359 mPendingServices.remove(i);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002360 }
2361 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002362 }
2363
2364 // Make sure we have no more records on the stopping list.
Dianne Hackborn164371f2013-10-01 19:10:13 -07002365 int i = mDestroyingServices.size();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002366 while (i > 0) {
2367 i--;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002368 ServiceRecord sr = mDestroyingServices.get(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002369 if (sr.app == app) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07002370 sr.forceClearTracker();
2371 mDestroyingServices.remove(i);
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002372 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "killServices remove destroying " + sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002373 }
2374 }
2375
2376 app.executingServices.clear();
2377 }
2378
2379 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
2380 ActivityManager.RunningServiceInfo info =
2381 new ActivityManager.RunningServiceInfo();
2382 info.service = r.name;
2383 if (r.app != null) {
2384 info.pid = r.app.pid;
2385 }
2386 info.uid = r.appInfo.uid;
2387 info.process = r.processName;
2388 info.foreground = r.isForeground;
2389 info.activeSince = r.createTime;
2390 info.started = r.startRequested;
2391 info.clientCount = r.connections.size();
2392 info.crashCount = r.crashCount;
2393 info.lastActivityTime = r.lastActivity;
2394 if (r.isForeground) {
2395 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
2396 }
2397 if (r.startRequested) {
2398 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
2399 }
2400 if (r.app != null && r.app.pid == ActivityManagerService.MY_PID) {
2401 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
2402 }
2403 if (r.app != null && r.app.persistent) {
2404 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
2405 }
2406
Dianne Hackborn390517b2013-05-30 15:03:32 -07002407 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2408 ArrayList<ConnectionRecord> connl = r.connections.valueAt(conni);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002409 for (int i=0; i<connl.size(); i++) {
2410 ConnectionRecord conn = connl.get(i);
2411 if (conn.clientLabel != 0) {
2412 info.clientPackage = conn.binding.client.info.packageName;
2413 info.clientLabel = conn.clientLabel;
2414 return info;
2415 }
2416 }
2417 }
2418 return info;
2419 }
2420
2421 List<ActivityManager.RunningServiceInfo> getRunningServiceInfoLocked(int maxNum,
2422 int flags) {
2423 ArrayList<ActivityManager.RunningServiceInfo> res
2424 = new ArrayList<ActivityManager.RunningServiceInfo>();
2425
Dianne Hackborn0c380492012-08-20 17:23:30 -07002426 final int uid = Binder.getCallingUid();
2427 final long ident = Binder.clearCallingIdentity();
2428 try {
2429 if (ActivityManager.checkUidPermission(
2430 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2431 uid) == PackageManager.PERMISSION_GRANTED) {
Dianne Hackborn1676c852012-09-10 14:52:30 -07002432 int[] users = mAm.getUsersLocked();
2433 for (int ui=0; ui<users.length && res.size() < maxNum; ui++) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002434 ArrayMap<ComponentName, ServiceRecord> alls = getServices(users[ui]);
2435 for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
2436 ServiceRecord sr = alls.valueAt(i);
2437 res.add(makeRunningServiceInfoLocked(sr));
Dianne Hackborn0c380492012-08-20 17:23:30 -07002438 }
2439 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002440
Dianne Hackborn0c380492012-08-20 17:23:30 -07002441 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
2442 ServiceRecord r = mRestartingServices.get(i);
2443 ActivityManager.RunningServiceInfo info =
2444 makeRunningServiceInfoLocked(r);
2445 info.restarting = r.nextRestartTime;
2446 res.add(info);
2447 }
2448 } else {
2449 int userId = UserHandle.getUserId(uid);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002450 ArrayMap<ComponentName, ServiceRecord> alls = getServices(userId);
2451 for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
2452 ServiceRecord sr = alls.valueAt(i);
2453 res.add(makeRunningServiceInfoLocked(sr));
Dianne Hackborn0c380492012-08-20 17:23:30 -07002454 }
2455
2456 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
2457 ServiceRecord r = mRestartingServices.get(i);
2458 if (r.userId == userId) {
2459 ActivityManager.RunningServiceInfo info =
2460 makeRunningServiceInfoLocked(r);
2461 info.restarting = r.nextRestartTime;
2462 res.add(info);
2463 }
2464 }
2465 }
2466 } finally {
2467 Binder.restoreCallingIdentity(ident);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002468 }
2469
2470 return res;
2471 }
2472
2473 public PendingIntent getRunningServiceControlPanelLocked(ComponentName name) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07002474 int userId = UserHandle.getUserId(Binder.getCallingUid());
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002475 ServiceRecord r = getServiceByName(name, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002476 if (r != null) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002477 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2478 ArrayList<ConnectionRecord> conn = r.connections.valueAt(conni);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002479 for (int i=0; i<conn.size(); i++) {
2480 if (conn.get(i).clientIntent != null) {
2481 return conn.get(i).clientIntent;
2482 }
2483 }
2484 }
2485 }
2486 return null;
2487 }
2488
2489 void serviceTimeout(ProcessRecord proc) {
2490 String anrMessage = null;
2491
Dianne Hackbornc2f6f942014-09-22 13:36:42 -07002492 synchronized(mAm) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002493 if (proc.executingServices.size() == 0 || proc.thread == null) {
2494 return;
2495 }
Dianne Hackbornab2df062015-01-07 13:43:13 -08002496 final long now = SystemClock.uptimeMillis();
2497 final long maxTime = now -
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002498 (proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002499 ServiceRecord timeout = null;
2500 long nextTime = 0;
Dianne Hackbornc8230512013-07-13 21:32:12 -07002501 for (int i=proc.executingServices.size()-1; i>=0; i--) {
2502 ServiceRecord sr = proc.executingServices.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002503 if (sr.executingStart < maxTime) {
2504 timeout = sr;
2505 break;
2506 }
2507 if (sr.executingStart > nextTime) {
2508 nextTime = sr.executingStart;
2509 }
2510 }
2511 if (timeout != null && mAm.mLruProcesses.contains(proc)) {
2512 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackborncff1bbf2015-01-20 13:43:32 -08002513 StringWriter sw = new StringWriter();
2514 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
2515 pw.println(timeout);
2516 timeout.dump(pw, " ");
2517 pw.close();
2518 mLastAnrDump = sw.toString();
2519 mAm.mHandler.removeCallbacks(mLastAnrDumpClearer);
2520 mAm.mHandler.postDelayed(mLastAnrDumpClearer, LAST_ANR_LIFETIME_DURATION_MSECS);
2521 anrMessage = "executing service " + timeout.shortName;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002522 } else {
2523 Message msg = mAm.mHandler.obtainMessage(
2524 ActivityManagerService.SERVICE_TIMEOUT_MSG);
2525 msg.obj = proc;
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002526 mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg
Dianne Hackborn2be00932013-09-22 16:46:00 -07002527 ? (nextTime+SERVICE_TIMEOUT) : (nextTime + SERVICE_BACKGROUND_TIMEOUT));
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002528 }
2529 }
2530
2531 if (anrMessage != null) {
Dianne Hackborn5fe7e2a2012-10-04 11:58:16 -07002532 mAm.appNotResponding(proc, null, null, false, anrMessage);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002533 }
2534 }
2535
Dianne Hackborn2be00932013-09-22 16:46:00 -07002536 void scheduleServiceTimeoutLocked(ProcessRecord proc) {
2537 if (proc.executingServices.size() == 0 || proc.thread == null) {
2538 return;
2539 }
2540 long now = SystemClock.uptimeMillis();
2541 Message msg = mAm.mHandler.obtainMessage(
2542 ActivityManagerService.SERVICE_TIMEOUT_MSG);
2543 msg.obj = proc;
2544 mAm.mHandler.sendMessageAtTime(msg,
2545 proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
2546 }
2547
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002548 /**
2549 * Prints a list of ServiceRecords (dumpsys activity services)
2550 */
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002551 void dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002552 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
2553 boolean needSep = false;
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002554 boolean printedAnything = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002555
2556 ItemMatcher matcher = new ItemMatcher();
2557 matcher.build(args, opti);
2558
2559 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
2560 try {
Dianne Hackborncff1bbf2015-01-20 13:43:32 -08002561 if (mLastAnrDump != null) {
2562 pw.println(" Last ANR service:");
2563 pw.print(mLastAnrDump);
2564 pw.println();
2565 }
Dianne Hackborn1676c852012-09-10 14:52:30 -07002566 int[] users = mAm.getUsersLocked();
2567 for (int user : users) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002568 ServiceMap smap = getServiceMap(user);
2569 boolean printed = false;
2570 if (smap.mServicesByName.size() > 0) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002571 long nowReal = SystemClock.elapsedRealtime();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002572 needSep = false;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002573 for (int si=0; si<smap.mServicesByName.size(); si++) {
2574 ServiceRecord r = smap.mServicesByName.valueAt(si);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002575 if (!matcher.match(r, r.name)) {
2576 continue;
2577 }
2578 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2579 continue;
2580 }
2581 if (!printed) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002582 if (printedAnything) {
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07002583 pw.println();
2584 }
Dianne Hackborn1676c852012-09-10 14:52:30 -07002585 pw.println(" User " + user + " active services:");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002586 printed = true;
2587 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002588 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002589 if (needSep) {
2590 pw.println();
2591 }
2592 pw.print(" * ");
2593 pw.println(r);
2594 if (dumpAll) {
2595 r.dump(pw, " ");
2596 needSep = true;
2597 } else {
2598 pw.print(" app=");
2599 pw.println(r.app);
2600 pw.print(" created=");
2601 TimeUtils.formatDuration(r.createTime, nowReal, pw);
2602 pw.print(" started=");
2603 pw.print(r.startRequested);
2604 pw.print(" connections=");
2605 pw.println(r.connections.size());
2606 if (r.connections.size() > 0) {
2607 pw.println(" Connections:");
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002608 for (int conni=0; conni<r.connections.size(); conni++) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002609 ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002610 for (int i = 0; i < clist.size(); i++) {
2611 ConnectionRecord conn = clist.get(i);
2612 pw.print(" ");
2613 pw.print(conn.binding.intent.intent.getIntent()
2614 .toShortString(false, false, false, false));
2615 pw.print(" -> ");
2616 ProcessRecord proc = conn.binding.client;
2617 pw.println(proc != null ? proc.toShortString() : "null");
2618 }
2619 }
2620 }
2621 }
2622 if (dumpClient && r.app != null && r.app.thread != null) {
2623 pw.println(" Client:");
2624 pw.flush();
2625 try {
2626 TransferPipe tp = new TransferPipe();
2627 try {
2628 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(),
2629 r, args);
2630 tp.setBufferPrefix(" ");
2631 // Short timeout, since blocking here can
2632 // deadlock with the application.
2633 tp.go(fd, 2000);
2634 } finally {
2635 tp.kill();
2636 }
2637 } catch (IOException e) {
2638 pw.println(" Failure while dumping the service: " + e);
2639 } catch (RemoteException e) {
2640 pw.println(" Got a RemoteException while dumping the service");
2641 }
2642 needSep = true;
2643 }
2644 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002645 needSep |= printed;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002646 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002647 printed = false;
2648 for (int si=0, SN=smap.mDelayedStartList.size(); si<SN; si++) {
2649 ServiceRecord r = smap.mDelayedStartList.get(si);
2650 if (!matcher.match(r, r.name)) {
2651 continue;
2652 }
2653 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2654 continue;
2655 }
2656 if (!printed) {
2657 if (printedAnything) {
2658 pw.println();
2659 }
2660 pw.println(" User " + user + " delayed start services:");
2661 printed = true;
2662 }
2663 printedAnything = true;
2664 pw.print(" * Delayed start "); pw.println(r);
2665 }
2666 printed = false;
2667 for (int si=0, SN=smap.mStartingBackground.size(); si<SN; si++) {
2668 ServiceRecord r = smap.mStartingBackground.get(si);
2669 if (!matcher.match(r, r.name)) {
2670 continue;
2671 }
2672 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2673 continue;
2674 }
2675 if (!printed) {
2676 if (printedAnything) {
2677 pw.println();
2678 }
2679 pw.println(" User " + user + " starting in background:");
2680 printed = true;
2681 }
2682 printedAnything = true;
2683 pw.print(" * Starting bg "); pw.println(r);
2684 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002685 }
Amith Yamasani258848d2012-08-10 17:06:33 -07002686 } catch (Exception e) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002687 Slog.w(TAG, "Exception in dumpServicesLocked", e);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002688 }
2689
2690 if (mPendingServices.size() > 0) {
2691 boolean printed = false;
2692 for (int i=0; i<mPendingServices.size(); i++) {
2693 ServiceRecord r = mPendingServices.get(i);
2694 if (!matcher.match(r, r.name)) {
2695 continue;
2696 }
2697 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2698 continue;
2699 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002700 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002701 if (!printed) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002702 if (needSep) pw.println();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002703 needSep = true;
2704 pw.println(" Pending services:");
2705 printed = true;
2706 }
2707 pw.print(" * Pending "); pw.println(r);
2708 r.dump(pw, " ");
2709 }
2710 needSep = true;
2711 }
2712
2713 if (mRestartingServices.size() > 0) {
2714 boolean printed = false;
2715 for (int i=0; i<mRestartingServices.size(); i++) {
2716 ServiceRecord r = mRestartingServices.get(i);
2717 if (!matcher.match(r, r.name)) {
2718 continue;
2719 }
2720 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2721 continue;
2722 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002723 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002724 if (!printed) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002725 if (needSep) pw.println();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002726 needSep = true;
2727 pw.println(" Restarting services:");
2728 printed = true;
2729 }
2730 pw.print(" * Restarting "); pw.println(r);
2731 r.dump(pw, " ");
2732 }
2733 needSep = true;
2734 }
2735
Dianne Hackborn164371f2013-10-01 19:10:13 -07002736 if (mDestroyingServices.size() > 0) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002737 boolean printed = false;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002738 for (int i=0; i< mDestroyingServices.size(); i++) {
2739 ServiceRecord r = mDestroyingServices.get(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002740 if (!matcher.match(r, r.name)) {
2741 continue;
2742 }
2743 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2744 continue;
2745 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002746 printedAnything = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002747 if (!printed) {
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002748 if (needSep) pw.println();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002749 needSep = true;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002750 pw.println(" Destroying services:");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002751 printed = true;
2752 }
Dianne Hackborn164371f2013-10-01 19:10:13 -07002753 pw.print(" * Destroy "); pw.println(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002754 r.dump(pw, " ");
2755 }
2756 needSep = true;
2757 }
2758
2759 if (dumpAll) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002760 boolean printed = false;
2761 for (int ic=0; ic<mServiceConnections.size(); ic++) {
2762 ArrayList<ConnectionRecord> r = mServiceConnections.valueAt(ic);
2763 for (int i=0; i<r.size(); i++) {
2764 ConnectionRecord cr = r.get(i);
2765 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
2766 continue;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002767 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002768 if (dumpPackage != null && (cr.binding.client == null
2769 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
2770 continue;
2771 }
2772 printedAnything = true;
2773 if (!printed) {
2774 if (needSep) pw.println();
2775 needSep = true;
2776 pw.println(" Connection bindings to services:");
2777 printed = true;
2778 }
2779 pw.print(" * "); pw.println(cr);
2780 cr.dump(pw, " ");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002781 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002782 }
2783 }
2784
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07002785 if (!printedAnything) {
2786 pw.println(" (nothing)");
2787 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002788 }
2789
2790 /**
2791 * There are three ways to call this:
2792 * - no service specified: dump all the services
2793 * - a flattened component name that matched an existing service was specified as the
2794 * first arg: dump that one service
2795 * - the first arg isn't the flattened component name of an existing service:
2796 * dump all services whose component contains the first arg as a substring
2797 */
2798 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
2799 int opti, boolean dumpAll) {
2800 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
2801
Dianne Hackbornc2f6f942014-09-22 13:36:42 -07002802 synchronized (mAm) {
Dianne Hackborn1676c852012-09-10 14:52:30 -07002803 int[] users = mAm.getUsersLocked();
2804 if ("all".equals(name)) {
2805 for (int user : users) {
Dianne Hackborn13c590d2013-10-07 14:32:00 -07002806 ServiceMap smap = mServiceMap.get(user);
2807 if (smap == null) {
2808 continue;
2809 }
2810 ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002811 for (int i=0; i<alls.size(); i++) {
2812 ServiceRecord r1 = alls.valueAt(i);
Amith Yamasani258848d2012-08-10 17:06:33 -07002813 services.add(r1);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002814 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002815 }
Dianne Hackborn1676c852012-09-10 14:52:30 -07002816 } else {
2817 ComponentName componentName = name != null
2818 ? ComponentName.unflattenFromString(name) : null;
2819 int objectId = 0;
2820 if (componentName == null) {
2821 // Not a '/' separated full component name; maybe an object ID?
2822 try {
2823 objectId = Integer.parseInt(name, 16);
2824 name = null;
2825 componentName = null;
2826 } catch (RuntimeException e) {
2827 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002828 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002829
Dianne Hackborn1676c852012-09-10 14:52:30 -07002830 for (int user : users) {
Dianne Hackborn13c590d2013-10-07 14:32:00 -07002831 ServiceMap smap = mServiceMap.get(user);
2832 if (smap == null) {
2833 continue;
2834 }
2835 ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002836 for (int i=0; i<alls.size(); i++) {
2837 ServiceRecord r1 = alls.valueAt(i);
Amith Yamasani258848d2012-08-10 17:06:33 -07002838 if (componentName != null) {
2839 if (r1.name.equals(componentName)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002840 services.add(r1);
2841 }
Amith Yamasani258848d2012-08-10 17:06:33 -07002842 } else if (name != null) {
2843 if (r1.name.flattenToString().contains(name)) {
2844 services.add(r1);
2845 }
2846 } else if (System.identityHashCode(r1) == objectId) {
2847 services.add(r1);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002848 }
2849 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002850 }
2851 }
2852 }
2853
2854 if (services.size() <= 0) {
2855 return false;
2856 }
2857
2858 boolean needSep = false;
2859 for (int i=0; i<services.size(); i++) {
2860 if (needSep) {
2861 pw.println();
2862 }
2863 needSep = true;
2864 dumpService("", fd, pw, services.get(i), args, dumpAll);
2865 }
2866 return true;
2867 }
2868
2869 /**
2870 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
2871 * there is a thread associated with the service.
2872 */
2873 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
2874 final ServiceRecord r, String[] args, boolean dumpAll) {
2875 String innerPrefix = prefix + " ";
Dianne Hackbornc2f6f942014-09-22 13:36:42 -07002876 synchronized (mAm) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002877 pw.print(prefix); pw.print("SERVICE ");
2878 pw.print(r.shortName); pw.print(" ");
2879 pw.print(Integer.toHexString(System.identityHashCode(r)));
2880 pw.print(" pid=");
2881 if (r.app != null) pw.println(r.app.pid);
2882 else pw.println("(not running)");
2883 if (dumpAll) {
2884 r.dump(pw, innerPrefix);
2885 }
2886 }
2887 if (r.app != null && r.app.thread != null) {
2888 pw.print(prefix); pw.println(" Client:");
2889 pw.flush();
2890 try {
2891 TransferPipe tp = new TransferPipe();
2892 try {
2893 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
2894 tp.setBufferPrefix(prefix + " ");
2895 tp.go(fd);
2896 } finally {
2897 tp.kill();
2898 }
2899 } catch (IOException e) {
2900 pw.println(prefix + " Failure while dumping the service: " + e);
2901 } catch (RemoteException e) {
2902 pw.println(prefix + " Got a RemoteException while dumping the service");
2903 }
2904 }
2905 }
2906
2907}