blob: 3f6a83f6ca01acfb4da31fb18569166cf7f7fdee [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;
Svet Ganov9c165d72015-12-01 19:52:26 -080033import android.content.IIntentSender;
34import android.content.IntentSender;
Christoph Studer365e4c32014-09-18 20:35:36 +020035import android.os.Build;
Svet Ganov9c165d72015-12-01 19:52:26 -080036import android.os.Bundle;
Craig Mautner4a8dddbf2014-08-13 10:49:26 -070037import android.os.DeadObjectException;
Dianne Hackborn9210bc82013-09-05 12:31:16 -070038import android.os.Handler;
Dianne Hackborn13c590d2013-10-07 14:32:00 -070039import android.os.Looper;
Svet Ganov9c165d72015-12-01 19:52:26 -080040import android.os.RemoteCallback;
Dianne Hackborn23037412013-11-04 18:11:29 -080041import android.os.SystemProperties;
Craig Mautner5f2bb4c2015-03-12 16:10:27 -070042import android.os.TransactionTooLargeException;
Dianne Hackborn9210bc82013-09-05 12:31:16 -070043import android.util.ArrayMap;
Dianne Hackborn465fa392014-09-14 14:21:18 -070044import android.util.ArraySet;
Wale Ogunwaled57969f2014-11-15 19:37:29 -080045
Joe Onorato4eb64fd2016-03-21 15:30:09 -070046import com.android.internal.app.procstats.ServiceState;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070047import com.android.internal.os.BatteryStatsImpl;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070048import com.android.internal.os.TransferPipe;
Dianne Hackborncff1bbf2015-01-20 13:43:32 -080049import com.android.internal.util.FastPrintWriter;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070050import com.android.server.am.ActivityManagerService.ItemMatcher;
51import com.android.server.am.ActivityManagerService.NeededUriGrants;
52
53import android.app.ActivityManager;
54import android.app.AppGlobals;
55import android.app.IApplicationThread;
56import android.app.IServiceConnection;
57import android.app.Notification;
58import android.app.PendingIntent;
59import android.app.Service;
60import android.content.ComponentName;
61import android.content.Context;
62import android.content.Intent;
63import android.content.pm.ApplicationInfo;
64import android.content.pm.PackageManager;
65import android.content.pm.ResolveInfo;
66import android.content.pm.ServiceInfo;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070067import android.os.Binder;
68import android.os.IBinder;
69import android.os.Message;
70import android.os.Process;
71import android.os.RemoteException;
72import android.os.SystemClock;
Dianne Hackbornf02b60a2012-08-16 10:48:27 -070073import android.os.UserHandle;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070074import android.util.EventLog;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070075import android.util.Slog;
76import android.util.SparseArray;
77import android.util.TimeUtils;
78
Dianne Hackbornbe4e6aa2013-06-07 13:25:29 -070079public final class ActiveServices {
Wale Ogunwaled57969f2014-11-15 19:37:29 -080080 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActiveServices" : TAG_AM;
81 private static final String TAG_MU = TAG + POSTFIX_MU;
82 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
83 private static final String TAG_SERVICE_EXECUTING = TAG + POSTFIX_SERVICE_EXECUTING;
84
85 private static final boolean DEBUG_DELAYED_SERVICE = DEBUG_SERVICE;
86 private static final boolean DEBUG_DELAYED_STARTS = DEBUG_DELAYED_SERVICE;
87
88 private static final boolean LOG_SERVICE_START_STOP = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070089
90 // How long we wait for a service to finish executing.
91 static final int SERVICE_TIMEOUT = 20*1000;
92
Dianne Hackbornbf36ee22013-07-26 18:24:10 -070093 // How long we wait for a service to finish executing.
94 static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
95
Dianne Hackborn599db5c2012-08-03 19:28:48 -070096 // How long a service needs to be running until restarting its process
97 // is no longer considered to be a relaunch of the service.
Dianne Hackborn7b492722013-11-01 09:58:45 -070098 static final int SERVICE_RESTART_DURATION = 1*1000;
Dianne Hackborn599db5c2012-08-03 19:28:48 -070099
100 // How long a service needs to be running until it will start back at
101 // SERVICE_RESTART_DURATION after being killed.
102 static final int SERVICE_RESET_RUN_DURATION = 60*1000;
103
104 // Multiplying factor to increase restart duration time by, for each time
105 // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
106 static final int SERVICE_RESTART_DURATION_FACTOR = 4;
107
108 // The minimum amount of time between restarting services that we allow.
109 // That is, when multiple services are restarting, we won't allow each
110 // to restart less than this amount of time from the last one.
111 static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
112
113 // Maximum amount of time for there to be no activity on a service before
114 // we consider it non-essential and allow its process to go on the
115 // LRU background list.
116 static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
117
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700118 // How long we wait for a background started service to stop itself before
119 // allowing the next pending start to run.
120 static final int BG_START_TIMEOUT = 15*1000;
121
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700122 final ActivityManagerService mAm;
123
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700124 // Maximum number of services that we allow to start in the background
125 // at the same time.
126 final int mMaxStartingBackground;
127
Wale Ogunwale540e1232015-05-01 15:35:39 -0700128 final SparseArray<ServiceMap> mServiceMap = new SparseArray<>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700129
130 /**
131 * All currently bound service connections. Keys are the IBinder of
132 * the client's IServiceConnection.
133 */
Wale Ogunwale540e1232015-05-01 15:35:39 -0700134 final ArrayMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections = new ArrayMap<>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700135
136 /**
137 * List of services that we have been asked to start,
138 * but haven't yet been able to. It is used to hold start requests
139 * while waiting for their corresponding application thread to get
140 * going.
141 */
Wale Ogunwale540e1232015-05-01 15:35:39 -0700142 final ArrayList<ServiceRecord> mPendingServices = new ArrayList<>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700143
144 /**
145 * List of services that are scheduled to restart following a crash.
146 */
Wale Ogunwale540e1232015-05-01 15:35:39 -0700147 final ArrayList<ServiceRecord> mRestartingServices = new ArrayList<>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700148
149 /**
Dianne Hackborn164371f2013-10-01 19:10:13 -0700150 * List of services that are in the process of being destroyed.
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700151 */
Wale Ogunwale540e1232015-05-01 15:35:39 -0700152 final ArrayList<ServiceRecord> mDestroyingServices = new ArrayList<>();
153
154 /** Temporary list for holding the results of calls to {@link #collectPackageServicesLocked} */
155 private ArrayList<ServiceRecord> mTmpCollectionResults = null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700156
Dianne Hackborncff1bbf2015-01-20 13:43:32 -0800157 /** Amount of time to allow a last ANR message to exist before freeing the memory. */
158 static final int LAST_ANR_LIFETIME_DURATION_MSECS = 2 * 60 * 60 * 1000; // Two hours
159
160 String mLastAnrDump;
161
162 final Runnable mLastAnrDumpClearer = new Runnable() {
163 @Override public void run() {
164 synchronized (mAm) {
165 mLastAnrDump = null;
166 }
167 }
168 };
169
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700170 /**
171 * Information about services for a single user.
172 */
173 class ServiceMap extends Handler {
Dianne Hackborn6285a322013-09-18 12:09:47 -0700174 final int mUserId;
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700175 final ArrayMap<ComponentName, ServiceRecord> mServicesByName = new ArrayMap<>();
176 final ArrayMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent = new ArrayMap<>();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700177
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700178 final ArrayList<ServiceRecord> mDelayedStartList = new ArrayList<>();
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700179 /* XXX eventually I'd like to have this based on processes instead of services.
180 * That is, if we try to start two services in a row both running in the same
181 * process, this should be one entry in mStartingBackground for that one process
182 * that remains until all services in it are done.
183 final ArrayMap<ProcessRecord, DelayingProcess> mStartingBackgroundMap
184 = new ArrayMap<ProcessRecord, DelayingProcess>();
185 final ArrayList<DelayingProcess> mStartingProcessList
186 = new ArrayList<DelayingProcess>();
187 */
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700188
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700189 final ArrayList<ServiceRecord> mStartingBackground = new ArrayList<>();
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,
Svet Ganov9c165d72015-12-01 19:52:26 -0800307 int callingPid, int callingUid, String callingPackage, final 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 Hackborna49ad092016-03-03 13:39:10 -0800321 callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700322 } 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,
Robert Sesekb9a86662015-12-09 16:22:45 -0500329 callingPid, callingUid, userId, true, callerFg, false);
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
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -0700340 if (!mAm.mUserController.exists(r.userId)) {
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700341 Slog.w(TAG, "Trying to start service with non-existent user! " + r.userId);
Adam Lesinskieddeb492014-09-08 17:50:03 -0700342 return null;
343 }
344
Dianne Hackborn4fb9c4a2016-04-04 13:31:18 -0700345 if (!r.startRequested) {
346 final long token = Binder.clearCallingIdentity();
347 try {
348 // Before going further -- if this app is not allowed to run in the
349 // background, then at this point we aren't going to let it period.
350 final int allowed = mAm.checkAllowBackgroundLocked(
351 r.appInfo.uid, r.packageName, callingPid, true);
352 if (allowed != ActivityManager.APP_START_MODE_NORMAL) {
353 Slog.w(TAG, "Background start not allowed: service "
354 + service + " to " + r.name.flattenToShortString()
355 + " from pid=" + callingPid + " uid=" + callingUid
356 + " pkg=" + callingPackage);
357 return null;
358 }
359 } finally {
360 Binder.restoreCallingIdentity(token);
361 }
362 }
363
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700364 NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
Nicolas Prevotc6cf95c2014-05-29 11:30:36 +0100365 callingUid, r.packageName, service, service.getFlags(), null, r.userId);
Svet Ganov9c165d72015-12-01 19:52:26 -0800366
367 // If permissions need a review before any of the app components can run,
368 // we do not start the service and launch a review activity if the calling app
369 // is in the foreground passing it a pending intent to start the service when
370 // review is completed.
Svetoslav Ganovb1e2da72016-06-29 17:31:44 -0700371 if (mAm.mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
Svet Ganov9c165d72015-12-01 19:52:26 -0800372 if (!requestStartTargetPermissionsReviewIfNeededLocked(r, callingPackage,
373 callingUid, service, callerFg, userId)) {
374 return null;
375 }
376 }
377
Dianne Hackbornd6f5b622013-11-11 17:25:37 -0800378 if (unscheduleServiceRestartLocked(r, callingUid, false)) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800379 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "START SERVICE WHILE RESTART PENDING: " + r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700380 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700381 r.lastActivity = SystemClock.uptimeMillis();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700382 r.startRequested = true;
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700383 r.delayedStop = false;
384 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
385 service, neededGrants));
386
387 final ServiceMap smap = getServiceMap(r.userId);
388 boolean addToStarting = false;
Fyodor Kupolov610acda2015-10-19 18:44:07 -0700389 if (!callerFg && r.app == null
390 && mAm.mUserController.hasStartedUserState(r.userId)) {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -0700391 ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700392 if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700393 // If this is not coming from a foreground caller, then we may want
394 // to delay the start if there are already other background services
395 // that are starting. This is to avoid process start spam when lots
396 // of applications are all handling things like connectivity broadcasts.
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700397 // We only do this for cached processes, because otherwise an application
398 // can have assumptions about calling startService() for a service to run
399 // in its own process, and for that process to not be killed before the
400 // service is started. This is especially the case for receivers, which
401 // may start a service in onReceive() to do some additional work and have
402 // initialized some global state as part of that.
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800403 if (DEBUG_DELAYED_SERVICE) Slog.v(TAG_SERVICE, "Potential start delay of "
404 + r + " in " + proc);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700405 if (r.delayed) {
406 // This service is already scheduled for a delayed start; just leave
407 // it still waiting.
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800408 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Continuing to delay: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700409 return r.name;
410 }
411 if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
412 // Something else is starting, delay!
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800413 Slog.i(TAG_SERVICE, "Delaying start of: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700414 smap.mDelayedStartList.add(r);
415 r.delayed = true;
416 return r.name;
417 }
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800418 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Not delaying: " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700419 addToStarting = true;
420 } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
421 // We slightly loosen when we will enqueue this new service as a background
422 // starting service we are waiting for, to also include processes that are
Dianne Hackborn0d97cd12013-09-16 19:02:52 -0700423 // currently running other services or receivers.
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700424 addToStarting = true;
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800425 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
426 "Not delaying, but counting as bg: " + r);
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800427 } else if (DEBUG_DELAYED_STARTS) {
Dianne Hackborn8e692572013-09-10 19:06:15 -0700428 StringBuilder sb = new StringBuilder(128);
429 sb.append("Not potential delay (state=").append(proc.curProcState)
430 .append(' ').append(proc.adjType);
431 String reason = proc.makeAdjReason();
432 if (reason != null) {
433 sb.append(' ');
434 sb.append(reason);
435 }
436 sb.append("): ");
437 sb.append(r.toString());
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800438 Slog.v(TAG_SERVICE, sb.toString());
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700439 }
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800440 } else if (DEBUG_DELAYED_STARTS) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700441 if (callerFg) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800442 Slog.v(TAG_SERVICE, "Not potential delay (callerFg=" + callerFg + " uid="
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700443 + callingUid + " pid=" + callingPid + "): " + r);
444 } else if (r.app != null) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800445 Slog.v(TAG_SERVICE, "Not potential delay (cur app=" + r.app + "): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700446 } else {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800447 Slog.v(TAG_SERVICE,
448 "Not potential delay (user " + r.userId + " not started): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700449 }
450 }
451
452 return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
453 }
454
Svet Ganov9c165d72015-12-01 19:52:26 -0800455 private boolean requestStartTargetPermissionsReviewIfNeededLocked(ServiceRecord r,
456 String callingPackage, int callingUid, Intent service, boolean callerFg,
457 final int userId) {
458 if (mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired(
459 r.packageName, r.userId)) {
460
461 // Show a permission review UI only for starting from a foreground app
462 if (!callerFg) {
463 Slog.w(TAG, "u" + r.userId + " Starting a service in package"
464 + r.packageName + " requires a permissions review");
465 return false;
466 }
467
468 IIntentSender target = mAm.getIntentSenderLocked(
469 ActivityManager.INTENT_SENDER_SERVICE, callingPackage,
470 callingUid, userId, null, null, 0, new Intent[]{service},
471 new String[]{service.resolveType(mAm.mContext.getContentResolver())},
472 PendingIntent.FLAG_CANCEL_CURRENT | PendingIntent.FLAG_ONE_SHOT
473 | PendingIntent.FLAG_IMMUTABLE, null);
474
475 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
476 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
477 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
478 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, r.packageName);
479 intent.putExtra(Intent.EXTRA_INTENT, new IntentSender(target));
480
481 if (DEBUG_PERMISSIONS_REVIEW) {
482 Slog.i(TAG, "u" + r.userId + " Launching permission review for package "
483 + r.packageName);
484 }
485
486 mAm.mHandler.post(new Runnable() {
487 @Override
488 public void run() {
489 mAm.mContext.startActivityAsUser(intent, new UserHandle(userId));
490 }
491 });
492
493 return false;
494 }
495
496 return true;
497 }
498
Craig Mautner5f2bb4c2015-03-12 16:10:27 -0700499 ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
500 boolean callerFg, boolean addToStarting) throws TransactionTooLargeException {
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700501 ServiceState stracker = r.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -0700502 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700503 stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700504 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700505 r.callStart = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700506 synchronized (r.stats.getBatteryStats()) {
507 r.stats.startRunningLocked();
508 }
Svet Ganov9c165d72015-12-01 19:52:26 -0800509 String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false, false);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -0700510 if (error != null) {
511 return new ComponentName("!!", error);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700512 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700513
514 if (r.startRequested && addToStarting) {
515 boolean first = smap.mStartingBackground.size() == 0;
516 smap.mStartingBackground.add(r);
517 r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
518 if (DEBUG_DELAYED_SERVICE) {
519 RuntimeException here = new RuntimeException("here");
520 here.fillInStackTrace();
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800521 Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r, here);
Dianne Hackbornaa9875e2013-12-09 11:26:11 -0800522 } else if (DEBUG_DELAYED_STARTS) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800523 Slog.v(TAG_SERVICE, "Starting background (first=" + first + "): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700524 }
525 if (first) {
526 smap.rescheduleDelayedStarts();
527 }
528 } else if (callerFg) {
529 smap.ensureNotStartingBackground(r);
530 }
531
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700532 return r.name;
533 }
534
535 private void stopServiceLocked(ServiceRecord service) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700536 if (service.delayed) {
537 // If service isn't actually running, but is is being held in the
538 // delayed list, then we need to keep it started but note that it
539 // should be stopped once no longer delayed.
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800540 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "Delaying stop of pending: " + service);
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700541 service.delayedStop = true;
542 return;
543 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700544 synchronized (service.stats.getBatteryStats()) {
545 service.stats.stopRunningLocked();
546 }
547 service.startRequested = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700548 if (service.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700549 service.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700550 SystemClock.uptimeMillis());
551 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700552 service.callStart = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700553 bringDownServiceIfNeededLocked(service, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700554 }
555
556 int stopServiceLocked(IApplicationThread caller, Intent service,
Dianne Hackborn7767eac2012-08-23 18:25:40 -0700557 String resolvedType, int userId) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800558 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "stopService: " + service
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700559 + " type=" + resolvedType);
560
561 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
562 if (caller != null && callerApp == null) {
563 throw new SecurityException(
564 "Unable to find app for caller " + caller
565 + " (pid=" + Binder.getCallingPid()
566 + ") when stopping service " + service);
567 }
568
569 // If this service is active, make sure it is stopped.
Svet Ganov99b60432015-06-27 13:15:22 -0700570 ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, null,
Robert Sesekb9a86662015-12-09 16:22:45 -0500571 Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700572 if (r != null) {
573 if (r.record != null) {
574 final long origId = Binder.clearCallingIdentity();
575 try {
576 stopServiceLocked(r.record);
577 } finally {
578 Binder.restoreCallingIdentity(origId);
579 }
580 return 1;
581 }
582 return -1;
583 }
584
585 return 0;
586 }
587
Dianne Hackbornbef28fe2015-10-29 17:57:11 -0700588 void stopInBackgroundLocked(int uid) {
589 // Stop all services associated with this uid due to it going to the background
590 // stopped state.
591 ServiceMap services = mServiceMap.get(UserHandle.getUserId(uid));
592 ArrayList<ServiceRecord> stopping = null;
593 if (services != null) {
594 for (int i=services.mServicesByName.size()-1; i>=0; i--) {
595 ServiceRecord service = services.mServicesByName.valueAt(i);
596 if (service.appInfo.uid == uid && service.startRequested) {
597 if (mAm.mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND,
598 uid, service.packageName) != AppOpsManager.MODE_ALLOWED) {
599 if (stopping == null) {
600 stopping = new ArrayList<>();
601 stopping.add(service);
602 }
603 }
604 }
605 }
606 if (stopping != null) {
607 for (int i=stopping.size()-1; i>=0; i--) {
608 ServiceRecord service = stopping.get(i);
609 service.delayed = false;
610 services.ensureNotStartingBackground(service);
611 stopServiceLocked(service);
612 }
613 }
614 }
615 }
616
Svet Ganov99b60432015-06-27 13:15:22 -0700617 IBinder peekServiceLocked(Intent service, String resolvedType, String callingPackage) {
618 ServiceLookupResult r = retrieveServiceLocked(service, resolvedType, callingPackage,
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -0700619 Binder.getCallingPid(), Binder.getCallingUid(),
Robert Sesekb9a86662015-12-09 16:22:45 -0500620 UserHandle.getCallingUserId(), false, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700621
622 IBinder ret = null;
623 if (r != null) {
624 // r.record is null if findServiceLocked() failed the caller permission check
625 if (r.record == null) {
626 throw new SecurityException(
Christopher Desjardins5862c5f2015-05-19 11:25:40 +0000627 "Permission Denial: Accessing service"
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700628 + " from pid=" + Binder.getCallingPid()
629 + ", uid=" + Binder.getCallingUid()
630 + " requires " + r.permission);
631 }
632 IntentBindRecord ib = r.record.bindings.get(r.record.intent);
633 if (ib != null) {
634 ret = ib.binder;
635 }
636 }
637
638 return ret;
639 }
640
641 boolean stopServiceTokenLocked(ComponentName className, IBinder token,
642 int startId) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800643 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "stopServiceToken: " + className
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700644 + " " + token + " startId=" + startId);
Dianne Hackborn41203752012-08-31 14:05:51 -0700645 ServiceRecord r = findServiceLocked(className, token, UserHandle.getCallingUserId());
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700646 if (r != null) {
647 if (startId >= 0) {
648 // Asked to only stop if done with all work. Note that
649 // to avoid leaks, we will take this as dropping all
650 // start items up to and including this one.
651 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
652 if (si != null) {
653 while (r.deliveredStarts.size() > 0) {
654 ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
655 cur.removeUriPermissionsLocked();
656 if (cur == si) {
657 break;
658 }
659 }
660 }
661
662 if (r.getLastStartId() != startId) {
663 return false;
664 }
665
666 if (r.deliveredStarts.size() > 0) {
667 Slog.w(TAG, "stopServiceToken startId " + startId
668 + " is last, but have " + r.deliveredStarts.size()
669 + " remaining args");
670 }
671 }
672
673 synchronized (r.stats.getBatteryStats()) {
674 r.stats.stopRunningLocked();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700675 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700676 r.startRequested = false;
677 if (r.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -0700678 r.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700679 SystemClock.uptimeMillis());
680 }
681 r.callStart = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700682 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700683 bringDownServiceIfNeededLocked(r, false, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700684 Binder.restoreCallingIdentity(origId);
685 return true;
686 }
687 return false;
688 }
689
690 public void setServiceForegroundLocked(ComponentName className, IBinder token,
Dianne Hackborn67324c92016-04-18 13:55:25 -0700691 int id, Notification notification, int flags) {
Dianne Hackborn41203752012-08-31 14:05:51 -0700692 final int userId = UserHandle.getCallingUserId();
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700693 final long origId = Binder.clearCallingIdentity();
694 try {
Dianne Hackborn41203752012-08-31 14:05:51 -0700695 ServiceRecord r = findServiceLocked(className, token, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700696 if (r != null) {
697 if (id != 0) {
698 if (notification == null) {
699 throw new IllegalArgumentException("null notification");
700 }
701 if (r.foregroundId != id) {
Dianne Hackborn0ba4c712016-08-01 17:49:41 -0700702 cancelForegroudNotificationLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700703 r.foregroundId = id;
704 }
705 notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
706 r.foregroundNoti = notification;
707 r.isForeground = true;
708 r.postNotification();
709 if (r.app != null) {
710 updateServiceForegroundLocked(r.app, true);
711 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -0700712 getServiceMap(r.userId).ensureNotStartingBackground(r);
Brian Carlstromca82e612016-04-19 23:16:08 -0700713 mAm.notifyPackageUse(r.serviceInfo.packageName,
714 PackageManager.NOTIFY_PACKAGE_USE_FOREGROUND_SERVICE);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700715 } else {
716 if (r.isForeground) {
717 r.isForeground = false;
718 if (r.app != null) {
Dianne Hackborndb926082013-10-31 16:32:44 -0700719 mAm.updateLruProcessLocked(r.app, false, null);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700720 updateServiceForegroundLocked(r.app, true);
721 }
722 }
Dianne Hackborn67324c92016-04-18 13:55:25 -0700723 if ((flags & Service.STOP_FOREGROUND_REMOVE) != 0) {
Dianne Hackborn0ba4c712016-08-01 17:49:41 -0700724 cancelForegroudNotificationLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700725 r.foregroundId = 0;
726 r.foregroundNoti = null;
Dianne Hackborn955d8d62014-10-07 20:17:19 -0700727 } else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
Christoph Studer365e4c32014-09-18 20:35:36 +0200728 r.stripForegroundServiceFlagFromNotification();
Dianne Hackborn67324c92016-04-18 13:55:25 -0700729 if ((flags & Service.STOP_FOREGROUND_DETACH) != 0) {
730 r.foregroundId = 0;
731 r.foregroundNoti = null;
732 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700733 }
734 }
735 }
736 } finally {
737 Binder.restoreCallingIdentity(origId);
738 }
739 }
740
Dianne Hackborn0ba4c712016-08-01 17:49:41 -0700741 private void cancelForegroudNotificationLocked(ServiceRecord r) {
742 if (r.foregroundId != 0) {
743 // First check to see if this app has any other active foreground services
744 // with the same notification ID. If so, we shouldn't actually cancel it,
745 // because that would wipe away the notification that still needs to be shown
746 // due the other service.
747 ServiceMap sm = getServiceMap(r.userId);
748 if (sm != null) {
749 for (int i = sm.mServicesByName.size()-1; i >= 0; i--) {
750 ServiceRecord other = sm.mServicesByName.valueAt(i);
Dianne Hackborn569a4582016-08-04 14:00:22 -0700751 if (other != r && other.foregroundId == r.foregroundId
Dianne Hackborn0ba4c712016-08-01 17:49:41 -0700752 && other.packageName.equals(r.packageName)) {
753 // Found one! Abort the cancel.
754 return;
755 }
756 }
757 }
758 r.cancelNotification();
759 }
760 }
761
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700762 private void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
763 boolean anyForeground = false;
Dianne Hackbornc8230512013-07-13 21:32:12 -0700764 for (int i=proc.services.size()-1; i>=0; i--) {
765 ServiceRecord sr = proc.services.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700766 if (sr.isForeground) {
767 anyForeground = true;
768 break;
769 }
770 }
Dianne Hackborneaf2ac42014-02-07 13:01:07 -0800771 mAm.updateProcessForegroundLocked(proc, anyForeground, oomAdj);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700772 }
773
Dianne Hackborna590d2b2016-06-27 15:07:18 -0700774 private void updateWhitelistManagerLocked(ProcessRecord proc) {
775 proc.whitelistManager = false;
776 for (int i=proc.services.size()-1; i>=0; i--) {
777 ServiceRecord sr = proc.services.valueAt(i);
778 if (sr.whitelistManager) {
779 proc.whitelistManager = true;
780 break;
781 }
782 }
783 }
784
Dianne Hackborn465fa392014-09-14 14:21:18 -0700785 public void updateServiceConnectionActivitiesLocked(ProcessRecord clientProc) {
786 ArraySet<ProcessRecord> updatedProcesses = null;
Wale Ogunwaled6ac7622016-05-26 09:02:25 -0700787 for (int i = 0; i < clientProc.connections.size(); i++) {
Dianne Hackborn465fa392014-09-14 14:21:18 -0700788 final ConnectionRecord conn = clientProc.connections.valueAt(i);
789 final ProcessRecord proc = conn.binding.service.app;
790 if (proc == null || proc == clientProc) {
791 continue;
792 } else if (updatedProcesses == null) {
793 updatedProcesses = new ArraySet<>();
794 } else if (updatedProcesses.contains(proc)) {
795 continue;
796 }
797 updatedProcesses.add(proc);
798 updateServiceClientActivitiesLocked(proc, null, false);
799 }
800 }
801
Dianne Hackborndb926082013-10-31 16:32:44 -0700802 private boolean updateServiceClientActivitiesLocked(ProcessRecord proc,
Dianne Hackborn465fa392014-09-14 14:21:18 -0700803 ConnectionRecord modCr, boolean updateLru) {
Dianne Hackborndb926082013-10-31 16:32:44 -0700804 if (modCr != null && modCr.binding.client != null) {
805 if (modCr.binding.client.activities.size() <= 0) {
806 // This connection is from a client without activities, so adding
807 // and removing is not interesting.
808 return false;
809 }
810 }
811
812 boolean anyClientActivities = false;
813 for (int i=proc.services.size()-1; i>=0 && !anyClientActivities; i--) {
814 ServiceRecord sr = proc.services.valueAt(i);
815 for (int conni=sr.connections.size()-1; conni>=0 && !anyClientActivities; conni--) {
816 ArrayList<ConnectionRecord> clist = sr.connections.valueAt(conni);
817 for (int cri=clist.size()-1; cri>=0; cri--) {
818 ConnectionRecord cr = clist.get(cri);
819 if (cr.binding.client == null || cr.binding.client == proc) {
820 // Binding to ourself is not interesting.
821 continue;
822 }
823 if (cr.binding.client.activities.size() > 0) {
824 anyClientActivities = true;
825 break;
826 }
827 }
828 }
829 }
830 if (anyClientActivities != proc.hasClientActivities) {
831 proc.hasClientActivities = anyClientActivities;
Dianne Hackborn465fa392014-09-14 14:21:18 -0700832 if (updateLru) {
833 mAm.updateLruProcessLocked(proc, anyClientActivities, null);
834 }
Dianne Hackborndb926082013-10-31 16:32:44 -0700835 return true;
836 }
837 return false;
838 }
839
Craig Mautner5f2bb4c2015-03-12 16:10:27 -0700840 int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service,
Svet Ganov9c165d72015-12-01 19:52:26 -0800841 String resolvedType, final IServiceConnection connection, int flags,
842 String callingPackage, final int userId) throws TransactionTooLargeException {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800843 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "bindService: " + service
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700844 + " type=" + resolvedType + " conn=" + connection.asBinder()
845 + " flags=0x" + Integer.toHexString(flags));
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700846 final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
847 if (callerApp == null) {
848 throw new SecurityException(
849 "Unable to find app for caller " + caller
850 + " (pid=" + Binder.getCallingPid()
851 + ") when binding service " + service);
852 }
853
854 ActivityRecord activity = null;
855 if (token != null) {
Craig Mautnerd2328952013-03-05 12:46:26 -0800856 activity = ActivityRecord.isInStackLocked(token);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700857 if (activity == null) {
858 Slog.w(TAG, "Binding with unknown activity: " + token);
859 return 0;
860 }
861 }
862
863 int clientLabel = 0;
864 PendingIntent clientIntent = null;
Felipe Lemea1b79bf2016-05-24 13:06:54 -0700865 final boolean isCallerSystem = callerApp.info.uid == Process.SYSTEM_UID;
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700866
Felipe Lemea1b79bf2016-05-24 13:06:54 -0700867 if (isCallerSystem) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700868 // Hacky kind of thing -- allow system stuff to tell us
869 // what they are, so we can report this elsewhere for
870 // others to know why certain services are running.
Jeff Sharkeyf0ec2e02016-03-21 12:37:54 -0600871 service.setDefusable(true);
872 clientIntent = service.getParcelableExtra(Intent.EXTRA_CLIENT_INTENT);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700873 if (clientIntent != null) {
874 clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
875 if (clientLabel != 0) {
876 // There are no useful extras in the intent, trash them.
877 // System code calling with this stuff just needs to know
878 // this will happen.
879 service = service.cloneFilter();
880 }
881 }
882 }
883
Dianne Hackbornf0f94d12014-03-17 16:04:21 -0700884 if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
885 mAm.enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
886 "BIND_TREAT_LIKE_ACTIVITY");
887 }
888
Felipe Lemea1b79bf2016-05-24 13:06:54 -0700889 if ((flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0 && !isCallerSystem) {
890 throw new SecurityException(
891 "Non-system caller " + caller + " (pid=" + Binder.getCallingPid()
892 + ") set BIND_ALLOW_WHITELIST_MANAGEMENT when binding service " + service);
893 }
894
Dianne Hackborna49ad092016-03-03 13:39:10 -0800895 final boolean callerFg = callerApp.setSchedGroup != ProcessList.SCHED_GROUP_BACKGROUND;
Robert Sesekb9a86662015-12-09 16:22:45 -0500896 final boolean isBindExternal = (flags & Context.BIND_EXTERNAL_SERVICE) != 0;
Dianne Hackbornbf36ee22013-07-26 18:24:10 -0700897
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700898 ServiceLookupResult res =
Robert Sesekb9a86662015-12-09 16:22:45 -0500899 retrieveServiceLocked(service, resolvedType, callingPackage, Binder.getCallingPid(),
900 Binder.getCallingUid(), userId, true, callerFg, isBindExternal);
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700901 if (res == null) {
902 return 0;
903 }
904 if (res.record == null) {
905 return -1;
906 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700907 ServiceRecord s = res.record;
908
Svet Ganov9c165d72015-12-01 19:52:26 -0800909 boolean permissionsReviewRequired = false;
910
911 // If permissions need a review before any of the app components can run,
912 // we schedule binding to the service but do not start its process, then
913 // we launch a review activity to which is passed a callback to invoke
914 // when done to start the bound service's process to completing the binding.
Svetoslav Ganovb1e2da72016-06-29 17:31:44 -0700915 if (mAm.mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
Svet Ganov9c165d72015-12-01 19:52:26 -0800916 if (mAm.getPackageManagerInternalLocked().isPermissionsReviewRequired(
917 s.packageName, s.userId)) {
918
919 permissionsReviewRequired = true;
920
921 // Show a permission review UI only for binding from a foreground app
922 if (!callerFg) {
923 Slog.w(TAG, "u" + s.userId + " Binding to a service in package"
924 + s.packageName + " requires a permissions review");
925 return 0;
926 }
927
928 final ServiceRecord serviceRecord = s;
929 final Intent serviceIntent = service;
930
931 RemoteCallback callback = new RemoteCallback(
932 new RemoteCallback.OnResultListener() {
933 @Override
934 public void onResult(Bundle result) {
935 synchronized(mAm) {
936 final long identity = Binder.clearCallingIdentity();
937 try {
938 if (!mPendingServices.contains(serviceRecord)) {
939 return;
940 }
941 // If there is still a pending record, then the service
942 // binding request is still valid, so hook them up. We
943 // proceed only if the caller cleared the review requirement
944 // otherwise we unbind because the user didn't approve.
945 if (!mAm.getPackageManagerInternalLocked()
946 .isPermissionsReviewRequired(
947 serviceRecord.packageName,
948 serviceRecord.userId)) {
949 try {
950 bringUpServiceLocked(serviceRecord,
951 serviceIntent.getFlags(),
952 callerFg, false, false);
953 } catch (RemoteException e) {
954 /* ignore - local call */
955 }
956 } else {
957 unbindServiceLocked(connection);
958 }
959 } finally {
960 Binder.restoreCallingIdentity(identity);
961 }
962 }
963 }
964 });
965
966 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
967 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
968 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
969 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, s.packageName);
970 intent.putExtra(Intent.EXTRA_REMOTE_CALLBACK, callback);
971
972 if (DEBUG_PERMISSIONS_REVIEW) {
973 Slog.i(TAG, "u" + s.userId + " Launching permission review for package "
974 + s.packageName);
975 }
976
977 mAm.mHandler.post(new Runnable() {
978 @Override
979 public void run() {
980 mAm.mContext.startActivityAsUser(intent, new UserHandle(userId));
981 }
982 });
983 }
984 }
985
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700986 final long origId = Binder.clearCallingIdentity();
987
988 try {
Dianne Hackbornd6f5b622013-11-11 17:25:37 -0800989 if (unscheduleServiceRestartLocked(s, callerApp.info.uid, false)) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -0800990 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "BIND SERVICE WHILE RESTART PENDING: "
Dianne Hackborn599db5c2012-08-03 19:28:48 -0700991 + s);
992 }
993
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700994 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
995 s.lastActivity = SystemClock.uptimeMillis();
996 if (!s.hasAutoCreateConnections()) {
997 // This is the first binding, let the tracker know.
Joe Onorato4eb64fd2016-03-21 15:30:09 -0700998 ServiceState stracker = s.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -0700999 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001000 stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001001 s.lastActivity);
1002 }
1003 }
1004 }
1005
Joe Onorato05c9ecc2016-03-30 15:13:46 -07001006 mAm.startAssociationLocked(callerApp.uid, callerApp.processName, callerApp.curProcState,
Dianne Hackbornab2df062015-01-07 13:43:13 -08001007 s.appInfo.uid, s.name, s.processName);
1008
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001009 AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
1010 ConnectionRecord c = new ConnectionRecord(b, activity,
1011 connection, flags, clientLabel, clientIntent);
1012
1013 IBinder binder = connection.asBinder();
1014 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
1015 if (clist == null) {
1016 clist = new ArrayList<ConnectionRecord>();
1017 s.connections.put(binder, clist);
1018 }
1019 clist.add(c);
1020 b.connections.add(c);
1021 if (activity != null) {
1022 if (activity.connections == null) {
1023 activity.connections = new HashSet<ConnectionRecord>();
1024 }
1025 activity.connections.add(c);
1026 }
1027 b.client.connections.add(c);
1028 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
1029 b.client.hasAboveClient = true;
1030 }
Dianne Hackborna590d2b2016-06-27 15:07:18 -07001031 if ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
1032 s.whitelistManager = true;
1033 }
Dianne Hackborndb926082013-10-31 16:32:44 -07001034 if (s.app != null) {
Dianne Hackborn465fa392014-09-14 14:21:18 -07001035 updateServiceClientActivitiesLocked(s.app, c, true);
Dianne Hackborndb926082013-10-31 16:32:44 -07001036 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001037 clist = mServiceConnections.get(binder);
1038 if (clist == null) {
1039 clist = new ArrayList<ConnectionRecord>();
1040 mServiceConnections.put(binder, clist);
1041 }
1042 clist.add(c);
1043
1044 if ((flags&Context.BIND_AUTO_CREATE) != 0) {
1045 s.lastActivity = SystemClock.uptimeMillis();
Svet Ganov9c165d72015-12-01 19:52:26 -08001046 if (bringUpServiceLocked(s, service.getFlags(), callerFg, false,
1047 permissionsReviewRequired) != null) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001048 return 0;
1049 }
1050 }
1051
1052 if (s.app != null) {
Dianne Hackbornf0f94d12014-03-17 16:04:21 -07001053 if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
1054 s.app.treatLikeActivity = true;
1055 }
Dianne Hackborna590d2b2016-06-27 15:07:18 -07001056 if (s.whitelistManager) {
1057 s.app.whitelistManager = true;
1058 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001059 // This could have made the service more important.
Dianne Hackbornf0f94d12014-03-17 16:04:21 -07001060 mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities
1061 || s.app.treatLikeActivity, b.client);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001062 mAm.updateOomAdjLocked(s.app);
1063 }
1064
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001065 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bind " + s + " with " + b
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001066 + ": received=" + b.intent.received
1067 + " apps=" + b.intent.apps.size()
1068 + " doRebind=" + b.intent.doRebind);
1069
1070 if (s.app != null && b.intent.received) {
1071 // Service is already running, so we can immediately
1072 // publish the connection.
1073 try {
1074 c.conn.connected(s.name, b.intent.binder);
1075 } catch (Exception e) {
1076 Slog.w(TAG, "Failure sending service " + s.shortName
1077 + " to connection " + c.conn.asBinder()
1078 + " (in " + c.binding.client.processName + ")", e);
1079 }
1080
1081 // If this is the first app connected back to this binding,
1082 // and the service had previously asked to be told when
1083 // rebound, then do so.
1084 if (b.intent.apps.size() == 1 && b.intent.doRebind) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001085 requestServiceBindingLocked(s, b.intent, callerFg, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001086 }
1087 } else if (!b.intent.requested) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001088 requestServiceBindingLocked(s, b.intent, callerFg, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001089 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001090
1091 getServiceMap(s.userId).ensureNotStartingBackground(s);
1092
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001093 } finally {
1094 Binder.restoreCallingIdentity(origId);
1095 }
1096
1097 return 1;
1098 }
1099
Svet Ganov9c165d72015-12-01 19:52:26 -08001100 private void foo() {
1101
1102 }
1103
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001104 void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
1105 final long origId = Binder.clearCallingIdentity();
1106 try {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001107 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "PUBLISHING " + r
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001108 + " " + intent + ": " + service);
1109 if (r != null) {
1110 Intent.FilterComparison filter
1111 = new Intent.FilterComparison(intent);
1112 IntentBindRecord b = r.bindings.get(filter);
1113 if (b != null && !b.received) {
1114 b.binder = service;
1115 b.requested = true;
1116 b.received = true;
Dianne Hackborn390517b2013-05-30 15:03:32 -07001117 for (int conni=r.connections.size()-1; conni>=0; conni--) {
1118 ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
1119 for (int i=0; i<clist.size(); i++) {
1120 ConnectionRecord c = clist.get(i);
1121 if (!filter.equals(c.binding.intent.intent)) {
1122 if (DEBUG_SERVICE) Slog.v(
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001123 TAG_SERVICE, "Not publishing to: " + c);
Dianne Hackborn390517b2013-05-30 15:03:32 -07001124 if (DEBUG_SERVICE) Slog.v(
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001125 TAG_SERVICE, "Bound intent: " + c.binding.intent.intent);
Dianne Hackborn390517b2013-05-30 15:03:32 -07001126 if (DEBUG_SERVICE) Slog.v(
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001127 TAG_SERVICE, "Published intent: " + intent);
Dianne Hackborn390517b2013-05-30 15:03:32 -07001128 continue;
1129 }
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001130 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Publishing to: " + c);
Dianne Hackborn390517b2013-05-30 15:03:32 -07001131 try {
1132 c.conn.connected(r.name, service);
1133 } catch (Exception e) {
1134 Slog.w(TAG, "Failure sending service " + r.name +
1135 " to connection " + c.conn.asBinder() +
1136 " (in " + c.binding.client.processName + ")", e);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001137 }
1138 }
1139 }
1140 }
1141
Dianne Hackborn164371f2013-10-01 19:10:13 -07001142 serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001143 }
1144 } finally {
1145 Binder.restoreCallingIdentity(origId);
1146 }
1147 }
1148
1149 boolean unbindServiceLocked(IServiceConnection connection) {
1150 IBinder binder = connection.asBinder();
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001151 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "unbindService: conn=" + binder);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001152 ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
1153 if (clist == null) {
1154 Slog.w(TAG, "Unbind failed: could not find connection for "
1155 + connection.asBinder());
1156 return false;
1157 }
1158
1159 final long origId = Binder.clearCallingIdentity();
1160 try {
1161 while (clist.size() > 0) {
1162 ConnectionRecord r = clist.get(0);
1163 removeConnectionLocked(r, null, null);
Dianne Hackborn25e1eca2014-09-23 10:13:13 -07001164 if (clist.size() > 0 && clist.get(0) == r) {
1165 // In case it didn't get removed above, do it now.
1166 Slog.wtf(TAG, "Connection " + r + " not removed for binder " + binder);
1167 clist.remove(0);
1168 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001169
1170 if (r.binding.service.app != null) {
Felipe Lemea1b79bf2016-05-24 13:06:54 -07001171 if (r.binding.service.app.whitelistManager) {
Felipe Lemea7778b02016-06-28 10:38:59 -07001172 updateWhitelistManagerLocked(r.binding.service.app);
Felipe Lemea1b79bf2016-05-24 13:06:54 -07001173 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001174 // This could have made the service less important.
Dianne Hackbornf0f94d12014-03-17 16:04:21 -07001175 if ((r.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
1176 r.binding.service.app.treatLikeActivity = true;
1177 mAm.updateLruProcessLocked(r.binding.service.app,
1178 r.binding.service.app.hasClientActivities
1179 || r.binding.service.app.treatLikeActivity, null);
1180 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001181 mAm.updateOomAdjLocked(r.binding.service.app);
1182 }
1183 }
1184 } finally {
1185 Binder.restoreCallingIdentity(origId);
1186 }
1187
1188 return true;
1189 }
1190
1191 void unbindFinishedLocked(ServiceRecord r, Intent intent, boolean doRebind) {
1192 final long origId = Binder.clearCallingIdentity();
1193 try {
1194 if (r != null) {
1195 Intent.FilterComparison filter
1196 = new Intent.FilterComparison(intent);
1197 IntentBindRecord b = r.bindings.get(filter);
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001198 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "unbindFinished in " + r
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001199 + " at " + b + ": apps="
1200 + (b != null ? b.apps.size() : 0));
1201
Dianne Hackborn164371f2013-10-01 19:10:13 -07001202 boolean inDestroying = mDestroyingServices.contains(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001203 if (b != null) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001204 if (b.apps.size() > 0 && !inDestroying) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001205 // Applications have already bound since the last
1206 // unbind, so just rebind right here.
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001207 boolean inFg = false;
1208 for (int i=b.apps.size()-1; i>=0; i--) {
1209 ProcessRecord client = b.apps.valueAt(i).client;
1210 if (client != null && client.setSchedGroup
Dianne Hackborna49ad092016-03-03 13:39:10 -08001211 != ProcessList.SCHED_GROUP_BACKGROUND) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001212 inFg = true;
1213 break;
1214 }
1215 }
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001216 try {
1217 requestServiceBindingLocked(r, b, inFg, true);
1218 } catch (TransactionTooLargeException e) {
1219 // Don't pass this back to ActivityThread, it's unrelated.
1220 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001221 } else {
1222 // Note to tell the service the next time there is
1223 // a new client.
1224 b.doRebind = true;
1225 }
1226 }
1227
Dianne Hackborn164371f2013-10-01 19:10:13 -07001228 serviceDoneExecutingLocked(r, inDestroying, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001229 }
1230 } finally {
1231 Binder.restoreCallingIdentity(origId);
1232 }
1233 }
1234
1235 private final ServiceRecord findServiceLocked(ComponentName name,
Dianne Hackborn41203752012-08-31 14:05:51 -07001236 IBinder token, int userId) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001237 ServiceRecord r = getServiceByName(name, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001238 return r == token ? r : null;
1239 }
1240
1241 private final class ServiceLookupResult {
1242 final ServiceRecord record;
1243 final String permission;
1244
1245 ServiceLookupResult(ServiceRecord _record, String _permission) {
1246 record = _record;
1247 permission = _permission;
1248 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001249 }
1250
1251 private class ServiceRestarter implements Runnable {
1252 private ServiceRecord mService;
1253
1254 void setService(ServiceRecord service) {
1255 mService = service;
1256 }
1257
1258 public void run() {
1259 synchronized(mAm) {
1260 performServiceRestartLocked(mService);
1261 }
1262 }
1263 }
1264
1265 private ServiceLookupResult retrieveServiceLocked(Intent service,
Svet Ganov99b60432015-06-27 13:15:22 -07001266 String resolvedType, String callingPackage, int callingPid, int callingUid, int userId,
Robert Sesekb9a86662015-12-09 16:22:45 -05001267 boolean createIfNeeded, boolean callingFromFg, boolean isBindExternal) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001268 ServiceRecord r = null;
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001269 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "retrieveServiceLocked: " + service
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001270 + " type=" + resolvedType + " callingUid=" + callingUid);
1271
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07001272 userId = mAm.mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
1273 ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE, "service", null);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001274
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001275 ServiceMap smap = getServiceMap(userId);
1276 final ComponentName comp = service.getComponent();
1277 if (comp != null) {
1278 r = smap.mServicesByName.get(comp);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001279 }
Robert Sesekb9a86662015-12-09 16:22:45 -05001280 if (r == null && !isBindExternal) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001281 Intent.FilterComparison filter = new Intent.FilterComparison(service);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001282 r = smap.mServicesByIntent.get(filter);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001283 }
Robert Sesekb9a86662015-12-09 16:22:45 -05001284 if (r != null && (r.serviceInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0
1285 && !callingPackage.equals(r.packageName)) {
1286 // If an external service is running within its own package, other packages
1287 // should not bind to that instance.
1288 r = null;
1289 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001290 if (r == null) {
1291 try {
Jeff Sharkeyc5967e92016-01-07 18:50:29 -07001292 // TODO: come back and remove this assumption to triage all services
1293 ResolveInfo rInfo = AppGlobals.getPackageManager().resolveService(service,
1294 resolvedType, ActivityManagerService.STOCK_PM_FLAGS
1295 | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
1296 userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001297 ServiceInfo sInfo =
1298 rInfo != null ? rInfo.serviceInfo : null;
1299 if (sInfo == null) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001300 Slog.w(TAG_SERVICE, "Unable to start service " + service + " U=" + userId +
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001301 ": not found");
1302 return null;
1303 }
1304 ComponentName name = new ComponentName(
1305 sInfo.applicationInfo.packageName, sInfo.name);
Robert Sesekb9a86662015-12-09 16:22:45 -05001306 if ((sInfo.flags & ServiceInfo.FLAG_EXTERNAL_SERVICE) != 0) {
1307 if (isBindExternal) {
1308 if (!sInfo.exported) {
1309 throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " + name +
1310 " is not exported");
1311 }
1312 if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) == 0) {
1313 throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " + name +
1314 " is not an isolatedProcess");
1315 }
1316 // Run the service under the calling package's application.
1317 ApplicationInfo aInfo = AppGlobals.getPackageManager().getApplicationInfo(
1318 callingPackage, ActivityManagerService.STOCK_PM_FLAGS, userId);
1319 if (aInfo == null) {
1320 throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " +
1321 "could not resolve client package " + callingPackage);
1322 }
1323 sInfo = new ServiceInfo(sInfo);
1324 sInfo.applicationInfo = new ApplicationInfo(sInfo.applicationInfo);
1325 sInfo.applicationInfo.packageName = aInfo.packageName;
1326 sInfo.applicationInfo.uid = aInfo.uid;
1327 name = new ComponentName(aInfo.packageName, name.getClassName());
1328 service.setComponent(name);
1329 } else {
1330 throw new SecurityException("BIND_EXTERNAL_SERVICE required for " +
1331 name);
1332 }
1333 } else if (isBindExternal) {
1334 throw new SecurityException("BIND_EXTERNAL_SERVICE failed, " + name +
1335 " is not an externalService");
1336 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001337 if (userId > 0) {
Dianne Hackborn7d19e022012-08-07 19:12:33 -07001338 if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
Amith Yamasani4b9d79c2014-05-21 19:14:21 -07001339 sInfo.name, sInfo.flags)
1340 && mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001341 userId = 0;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001342 smap = getServiceMap(0);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001343 }
1344 sInfo = new ServiceInfo(sInfo);
1345 sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
1346 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001347 r = smap.mServicesByName.get(name);
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001348 if (r == null && createIfNeeded) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001349 Intent.FilterComparison filter
1350 = new Intent.FilterComparison(service.cloneFilter());
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001351 ServiceRestarter res = new ServiceRestarter();
1352 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
1353 BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics();
1354 synchronized (stats) {
1355 ss = stats.getServiceStatsLocked(
1356 sInfo.applicationInfo.uid, sInfo.packageName,
1357 sInfo.name);
1358 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001359 r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001360 res.setService(r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001361 smap.mServicesByName.put(name, r);
1362 smap.mServicesByIntent.put(filter, r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001363
1364 // Make sure this component isn't in the pending list.
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001365 for (int i=mPendingServices.size()-1; i>=0; i--) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001366 ServiceRecord pr = mPendingServices.get(i);
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001367 if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
1368 && pr.name.equals(name)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001369 mPendingServices.remove(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001370 }
1371 }
1372 }
1373 } catch (RemoteException ex) {
1374 // pm is in same process, this will never happen.
1375 }
1376 }
1377 if (r != null) {
1378 if (mAm.checkComponentPermission(r.permission,
1379 callingPid, callingUid, r.appInfo.uid, r.exported)
1380 != PackageManager.PERMISSION_GRANTED) {
1381 if (!r.exported) {
1382 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
1383 + " from pid=" + callingPid
1384 + ", uid=" + callingUid
1385 + " that is not exported from uid " + r.appInfo.uid);
1386 return new ServiceLookupResult(null, "not exported from uid "
1387 + r.appInfo.uid);
1388 }
1389 Slog.w(TAG, "Permission Denial: Accessing service " + r.name
1390 + " from pid=" + callingPid
1391 + ", uid=" + callingUid
1392 + " requires " + r.permission);
1393 return new ServiceLookupResult(null, r.permission);
Svet Ganov99b60432015-06-27 13:15:22 -07001394 } else if (r.permission != null && callingPackage != null) {
1395 final int opCode = AppOpsManager.permissionToOpCode(r.permission);
1396 if (opCode != AppOpsManager.OP_NONE && mAm.mAppOpsService.noteOperation(
1397 opCode, callingUid, callingPackage) != AppOpsManager.MODE_ALLOWED) {
1398 Slog.w(TAG, "Appop Denial: Accessing service " + r.name
1399 + " from pid=" + callingPid
1400 + ", uid=" + callingUid
1401 + " requires appop " + AppOpsManager.opToName(opCode));
1402 return null;
1403 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001404 }
Svet Ganov99b60432015-06-27 13:15:22 -07001405
Ben Gruverf5323fe2013-07-31 15:09:51 -07001406 if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
1407 resolvedType, r.appInfo)) {
Ben Gruverb6223792013-07-29 16:35:40 -07001408 return null;
1409 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001410 return new ServiceLookupResult(r, null);
1411 }
1412 return null;
1413 }
1414
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001415 private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001416 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, ">>> EXECUTING "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001417 + why + " of " + r + " in app " + r.app);
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001418 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING, ">>> EXECUTING "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001419 + why + " of " + r.shortName);
1420 long now = SystemClock.uptimeMillis();
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001421 if (r.executeNesting == 0) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001422 r.executeFg = fg;
Joe Onorato4eb64fd2016-03-21 15:30:09 -07001423 ServiceState stracker = r.getTracker();
Dianne Hackbornbd754f42013-07-23 15:52:36 -07001424 if (stracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07001425 stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001426 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001427 if (r.app != null) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001428 r.app.executingServices.add(r);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001429 r.app.execServicesFg |= fg;
Dianne Hackborn2be00932013-09-22 16:46:00 -07001430 if (r.app.executingServices.size() == 1) {
1431 scheduleServiceTimeoutLocked(r.app);
1432 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001433 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001434 } else if (r.app != null && fg && !r.app.execServicesFg) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001435 r.app.execServicesFg = true;
Dianne Hackborn2be00932013-09-22 16:46:00 -07001436 scheduleServiceTimeoutLocked(r.app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001437 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001438 r.executeFg |= fg;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001439 r.executeNesting++;
1440 r.executingStart = now;
1441 }
1442
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001443 private final boolean requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i,
1444 boolean execInFg, boolean rebind) throws TransactionTooLargeException {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001445 if (r.app == null || r.app.thread == null) {
1446 // If service is not currently running, can't yet bind.
1447 return false;
1448 }
1449 if ((!i.requested || rebind) && i.apps.size() > 0) {
1450 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001451 bumpServiceExecutingLocked(r, execInFg, "bind");
Dianne Hackborna413dc02013-07-12 12:02:55 -07001452 r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
1453 r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
1454 r.app.repProcState);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001455 if (!rebind) {
1456 i.requested = true;
1457 }
1458 i.hasBound = true;
1459 i.doRebind = false;
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001460 } catch (TransactionTooLargeException e) {
1461 // Keep the executeNesting count accurate.
1462 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r, e);
1463 final boolean inDestroying = mDestroyingServices.contains(r);
1464 serviceDoneExecutingLocked(r, inDestroying, inDestroying);
1465 throw e;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001466 } catch (RemoteException e) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001467 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while binding " + r);
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001468 // Keep the executeNesting count accurate.
1469 final boolean inDestroying = mDestroyingServices.contains(r);
1470 serviceDoneExecutingLocked(r, inDestroying, inDestroying);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001471 return false;
1472 }
1473 }
1474 return true;
1475 }
1476
1477 private final boolean scheduleServiceRestartLocked(ServiceRecord r,
1478 boolean allowCancel) {
1479 boolean canceled = false;
1480
Fyodor Kupolov9b80b942016-06-16 16:29:05 -07001481 if (mAm.isShuttingDownLocked()) {
1482 Slog.w(TAG, "Not scheduling restart of crashed service " + r.shortName
1483 + " - system is shutting down");
1484 return false;
1485 }
1486
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001487 ServiceMap smap = getServiceMap(r.userId);
1488 if (smap.mServicesByName.get(r.name) != r) {
1489 ServiceRecord cur = smap.mServicesByName.get(r.name);
1490 Slog.wtf(TAG, "Attempting to schedule restart of " + r
1491 + " when found in map: " + cur);
1492 return false;
1493 }
1494
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001495 final long now = SystemClock.uptimeMillis();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001496
1497 if ((r.serviceInfo.applicationInfo.flags
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001498 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
1499 long minDuration = SERVICE_RESTART_DURATION;
1500 long resetTime = SERVICE_RESET_RUN_DURATION;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001501
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001502 // Any delivered but not yet finished starts should be put back
1503 // on the pending list.
1504 final int N = r.deliveredStarts.size();
1505 if (N > 0) {
1506 for (int i=N-1; i>=0; i--) {
1507 ServiceRecord.StartItem si = r.deliveredStarts.get(i);
1508 si.removeUriPermissionsLocked();
1509 if (si.intent == null) {
1510 // We'll generate this again if needed.
1511 } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
1512 && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
1513 r.pendingStarts.add(0, si);
1514 long dur = SystemClock.uptimeMillis() - si.deliveredTime;
1515 dur *= 2;
1516 if (minDuration < dur) minDuration = dur;
1517 if (resetTime < dur) resetTime = dur;
1518 } else {
1519 Slog.w(TAG, "Canceling start item " + si.intent + " in service "
1520 + r.name);
1521 canceled = true;
1522 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001523 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001524 r.deliveredStarts.clear();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001525 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001526
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001527 r.totalRestartCount++;
1528 if (r.restartDelay == 0) {
1529 r.restartCount++;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001530 r.restartDelay = minDuration;
1531 } else {
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001532 // If it has been a "reasonably long time" since the service
1533 // was started, then reset our restart duration back to
1534 // the beginning, so we don't infinitely increase the duration
1535 // on a service that just occasionally gets killed (which is
1536 // a normal case, due to process being killed to reclaim memory).
1537 if (now > (r.restartTime+resetTime)) {
1538 r.restartCount = 1;
1539 r.restartDelay = minDuration;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001540 } else {
Dianne Hackborn7b492722013-11-01 09:58:45 -07001541 r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
1542 if (r.restartDelay < minDuration) {
1543 r.restartDelay = minDuration;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001544 }
1545 }
1546 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001547
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001548 r.nextRestartTime = now + r.restartDelay;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001549
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001550 // Make sure that we don't end up restarting a bunch of services
1551 // all at the same time.
1552 boolean repeat;
1553 do {
1554 repeat = false;
1555 for (int i=mRestartingServices.size()-1; i>=0; i--) {
1556 ServiceRecord r2 = mRestartingServices.get(i);
1557 if (r2 != r && r.nextRestartTime
1558 >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
1559 && r.nextRestartTime
1560 < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
1561 r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
1562 r.restartDelay = r.nextRestartTime - now;
1563 repeat = true;
1564 break;
1565 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001566 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001567 } while (repeat);
1568
1569 } else {
Dianne Hackborn7b492722013-11-01 09:58:45 -07001570 // Persistent processes are immediately restarted, so there is no
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07001571 // reason to hold of on restarting their services.
1572 r.totalRestartCount++;
1573 r.restartCount = 0;
1574 r.restartDelay = 0;
1575 r.nextRestartTime = now;
1576 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001577
1578 if (!mRestartingServices.contains(r)) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001579 r.createdFromFg = false;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001580 mRestartingServices.add(r);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001581 r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001582 }
1583
Dianne Hackborn0ba4c712016-08-01 17:49:41 -07001584 cancelForegroudNotificationLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001585
1586 mAm.mHandler.removeCallbacks(r.restarter);
1587 mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime);
1588 r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
1589 Slog.w(TAG, "Scheduling restart of crashed service "
1590 + r.shortName + " in " + r.restartDelay + "ms");
1591 EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
Dianne Hackbornb12e1352012-09-26 11:39:20 -07001592 r.userId, r.shortName, r.restartDelay);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001593
1594 return canceled;
1595 }
1596
1597 final void performServiceRestartLocked(ServiceRecord r) {
1598 if (!mRestartingServices.contains(r)) {
1599 return;
1600 }
Dianne Hackborn865907d2015-10-21 17:12:53 -07001601 if (!isServiceNeeded(r, false, false)) {
1602 // Paranoia: is this service actually needed? In theory a service that is not
1603 // needed should never remain on the restart list. In practice... well, there
1604 // have been bugs where this happens, and bad things happen because the process
1605 // ends up just being cached, so quickly killed, then restarted again and again.
1606 // Let's not let that happen.
1607 Slog.wtf(TAG, "Restarting service that is not needed: " + r);
1608 return;
1609 }
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001610 try {
Svet Ganov9c165d72015-12-01 19:52:26 -08001611 bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true, false);
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001612 } catch (TransactionTooLargeException e) {
1613 // Ignore, it's been logged and nothing upstack cares.
1614 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001615 }
1616
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001617 private final boolean unscheduleServiceRestartLocked(ServiceRecord r, int callingUid,
1618 boolean force) {
1619 if (!force && r.restartDelay == 0) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001620 return false;
1621 }
Dianne Hackborn7b492722013-11-01 09:58:45 -07001622 // Remove from the restarting list; if the service is currently on the
1623 // restarting list, or the call is coming from another app, then this
1624 // service has become of much more interest so we reset the restart interval.
1625 boolean removed = mRestartingServices.remove(r);
1626 if (removed || callingUid != r.appInfo.uid) {
1627 r.resetRestartCounter();
1628 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001629 if (removed) {
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001630 clearRestartingIfNeededLocked(r);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001631 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001632 mAm.mHandler.removeCallbacks(r.restarter);
1633 return true;
1634 }
1635
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001636 private void clearRestartingIfNeededLocked(ServiceRecord r) {
1637 if (r.restartTracker != null) {
1638 // If this is the last restarting record with this tracker, then clear
1639 // the tracker's restarting state.
1640 boolean stillTracking = false;
1641 for (int i=mRestartingServices.size()-1; i>=0; i--) {
1642 if (mRestartingServices.get(i).restartTracker == r.restartTracker) {
1643 stillTracking = true;
1644 break;
1645 }
1646 }
1647 if (!stillTracking) {
1648 r.restartTracker.setRestarting(false, mAm.mProcessStats.getMemFactorLocked(),
1649 SystemClock.uptimeMillis());
1650 r.restartTracker = null;
1651 }
1652 }
1653 }
1654
Svet Ganov9c165d72015-12-01 19:52:26 -08001655 private String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg,
1656 boolean whileRestarting, boolean permissionsReviewRequired)
1657 throws TransactionTooLargeException {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001658 //Slog.i(TAG, "Bring up service:");
1659 //r.dump(" ");
1660
1661 if (r.app != null && r.app.thread != null) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001662 sendServiceArgsLocked(r, execInFg, false);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001663 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001664 }
1665
1666 if (!whileRestarting && r.restartDelay > 0) {
1667 // If waiting for a restart, then do nothing.
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001668 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001669 }
1670
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001671 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing up " + r + " " + r.intent);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001672
1673 // We are now bringing the service up, so no longer in the
1674 // restarting state.
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001675 if (mRestartingServices.remove(r)) {
chad7158ea22014-12-21 15:43:01 +08001676 r.resetRestartCounter();
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08001677 clearRestartingIfNeededLocked(r);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08001678 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001679
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001680 // Make sure this service is no longer considered delayed, we are starting it now.
1681 if (r.delayed) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001682 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (bring up): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001683 getServiceMap(r.userId).mDelayedStartList.remove(r);
1684 r.delayed = false;
1685 }
1686
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001687 // Make sure that the user who owns this service is started. If not,
1688 // we don't want to allow it to run.
Fyodor Kupolov610acda2015-10-19 18:44:07 -07001689 if (!mAm.mUserController.hasStartedUserState(r.userId)) {
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001690 String msg = "Unable to launch app "
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001691 + r.appInfo.packageName + "/"
1692 + r.appInfo.uid + " for service "
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001693 + r.intent.getIntent() + ": user " + r.userId + " is stopped";
1694 Slog.w(TAG, msg);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001695 bringDownServiceLocked(r);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001696 return msg;
Dianne Hackborn80a4af22012-08-27 19:18:31 -07001697 }
1698
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001699 // Service is now being launched, its package can't be stopped.
1700 try {
1701 AppGlobals.getPackageManager().setPackageStoppedState(
1702 r.packageName, false, r.userId);
1703 } catch (RemoteException e) {
1704 } catch (IllegalArgumentException e) {
1705 Slog.w(TAG, "Failed trying to unstop package "
1706 + r.packageName + ": " + e);
1707 }
1708
1709 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
1710 final String procName = r.processName;
1711 ProcessRecord app;
1712
1713 if (!isolated) {
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001714 app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
1715 if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
1716 + " app=" + app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001717 if (app != null && app.thread != null) {
1718 try {
Dianne Hackbornf7097a52014-05-13 09:56:14 -07001719 app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001720 realStartServiceLocked(r, app, execInFg);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001721 return null;
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001722 } catch (TransactionTooLargeException e) {
1723 throw e;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001724 } catch (RemoteException e) {
1725 Slog.w(TAG, "Exception when starting service " + r.shortName, e);
1726 }
1727
1728 // If a dead object exception was thrown -- fall through to
1729 // restart the application.
1730 }
1731 } else {
1732 // If this service runs in an isolated process, then each time
1733 // we call startProcessLocked() we will get a new isolated
1734 // process, starting another process if we are currently waiting
1735 // for a previous process to come up. To deal with this, we store
1736 // in the service any current isolated process it is running in or
1737 // waiting to have come up.
1738 app = r.isolatedProc;
1739 }
1740
1741 // Not running -- get it started, and enqueue this service record
1742 // to be executed when the app comes up.
Svet Ganov9c165d72015-12-01 19:52:26 -08001743 if (app == null && !permissionsReviewRequired) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001744 if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
Dianne Hackborn3bc8f78d2013-09-19 13:34:35 -07001745 "service", r.name, false, isolated, false)) == null) {
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001746 String msg = "Unable to launch app "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001747 + r.appInfo.packageName + "/"
1748 + r.appInfo.uid + " for service "
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001749 + r.intent.getIntent() + ": process is bad";
1750 Slog.w(TAG, msg);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001751 bringDownServiceLocked(r);
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001752 return msg;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001753 }
1754 if (isolated) {
1755 r.isolatedProc = app;
1756 }
1757 }
1758
1759 if (!mPendingServices.contains(r)) {
1760 mPendingServices.add(r);
1761 }
1762
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001763 if (r.delayedStop) {
1764 // Oh and hey we've already been asked to stop!
1765 r.delayedStop = false;
1766 if (r.startRequested) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001767 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
1768 "Applying delayed stop (in bring up): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001769 stopServiceLocked(r);
1770 }
1771 }
1772
Dianne Hackbornc0bd7472012-10-09 14:00:30 -07001773 return null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001774 }
1775
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001776 private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg)
1777 throws TransactionTooLargeException {
Dianne Hackborn390517b2013-05-30 15:03:32 -07001778 for (int i=r.bindings.size()-1; i>=0; i--) {
1779 IntentBindRecord ibr = r.bindings.valueAt(i);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001780 if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001781 break;
1782 }
1783 }
1784 }
1785
1786 private final void realStartServiceLocked(ServiceRecord r,
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001787 ProcessRecord app, boolean execInFg) throws RemoteException {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001788 if (app.thread == null) {
1789 throw new RemoteException();
1790 }
1791 if (DEBUG_MU)
1792 Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
1793 + ", ProcessRecord.uid = " + app.uid);
1794 r.app = app;
1795 r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
1796
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001797 final boolean newService = app.services.add(r);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001798 bumpServiceExecutingLocked(r, execInFg, "create");
Dianne Hackborndb926082013-10-31 16:32:44 -07001799 mAm.updateLruProcessLocked(app, false, null);
1800 mAm.updateOomAdjLocked();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001801
1802 boolean created = false;
1803 try {
Dianne Hackbornf85e7af2014-10-14 10:43:43 -07001804 if (LOG_SERVICE_START_STOP) {
Dianne Hackbornab2df062015-01-07 13:43:13 -08001805 String nameTerm;
1806 int lastPeriod = r.shortName.lastIndexOf('.');
1807 nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
Dianne Hackbornf85e7af2014-10-14 10:43:43 -07001808 EventLogTags.writeAmCreateService(
1809 r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
1810 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001811 synchronized (r.stats.getBatteryStats()) {
1812 r.stats.startLaunchedLocked();
1813 }
Brian Carlstromca82e612016-04-19 23:16:08 -07001814 mAm.notifyPackageUse(r.serviceInfo.packageName,
1815 PackageManager.NOTIFY_PACKAGE_USE_SERVICE);
Dianne Hackborna413dc02013-07-12 12:02:55 -07001816 app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001817 app.thread.scheduleCreateService(r, r.serviceInfo,
Dianne Hackborna413dc02013-07-12 12:02:55 -07001818 mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
1819 app.repProcState);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001820 r.postNotification();
1821 created = true;
Craig Mautner4a8dddbf2014-08-13 10:49:26 -07001822 } catch (DeadObjectException e) {
1823 Slog.w(TAG, "Application dead when creating service " + r);
1824 mAm.appDiedLocked(app);
Wale Ogunwalebfac4682015-04-08 14:33:21 -07001825 throw e;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001826 } finally {
1827 if (!created) {
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001828 // Keep the executeNesting count accurate.
1829 final boolean inDestroying = mDestroyingServices.contains(r);
1830 serviceDoneExecutingLocked(r, inDestroying, inDestroying);
1831
1832 // Cleanup.
1833 if (newService) {
1834 app.services.remove(r);
1835 r.app = null;
1836 }
1837
1838 // Retry.
1839 if (!inDestroying) {
1840 scheduleServiceRestartLocked(r, false);
1841 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001842 }
1843 }
1844
Dianne Hackborna590d2b2016-06-27 15:07:18 -07001845 if (r.whitelistManager) {
1846 app.whitelistManager = true;
1847 }
1848
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001849 requestServiceBindingsLocked(r, execInFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001850
Dianne Hackborn465fa392014-09-14 14:21:18 -07001851 updateServiceClientActivitiesLocked(app, null, true);
1852
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001853 // If the service is in the started state, and there are no
1854 // pending arguments, then fake up one so its onStartCommand() will
1855 // be called.
1856 if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
1857 r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
1858 null, null));
1859 }
1860
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001861 sendServiceArgsLocked(r, execInFg, true);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001862
1863 if (r.delayed) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001864 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE, "REM FR DELAY LIST (new proc): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001865 getServiceMap(r.userId).mDelayedStartList.remove(r);
1866 r.delayed = false;
1867 }
1868
1869 if (r.delayedStop) {
1870 // Oh and hey we've already been asked to stop!
1871 r.delayedStop = false;
1872 if (r.startRequested) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001873 if (DEBUG_DELAYED_STARTS) Slog.v(TAG_SERVICE,
1874 "Applying delayed stop (from start): " + r);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001875 stopServiceLocked(r);
1876 }
1877 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001878 }
1879
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001880 private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001881 boolean oomAdjusted) throws TransactionTooLargeException {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001882 final int N = r.pendingStarts.size();
1883 if (N == 0) {
1884 return;
1885 }
1886
1887 while (r.pendingStarts.size() > 0) {
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001888 Exception caughtException = null;
Yasuhiro Matsuda8b5cd9f2015-07-10 15:35:47 +09001889 ServiceRecord.StartItem si = null;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001890 try {
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001891 si = r.pendingStarts.remove(0);
Wale Ogunwaled57969f2014-11-15 19:37:29 -08001892 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Sending arguments to: "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001893 + r + " " + r.intent + " args=" + si.intent);
1894 if (si.intent == null && N > 1) {
1895 // If somehow we got a dummy null intent in the middle,
1896 // then skip it. DO NOT skip a null intent when it is
1897 // the only one in the list -- this is to support the
1898 // onStartCommand(null) case.
1899 continue;
1900 }
1901 si.deliveredTime = SystemClock.uptimeMillis();
1902 r.deliveredStarts.add(si);
1903 si.deliveryCount++;
1904 if (si.neededGrants != null) {
1905 mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
1906 si.getUriPermissionsLocked());
1907 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07001908 bumpServiceExecutingLocked(r, execInFg, "start");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001909 if (!oomAdjusted) {
1910 oomAdjusted = true;
1911 mAm.updateOomAdjLocked(r.app);
1912 }
1913 int flags = 0;
1914 if (si.deliveryCount > 1) {
1915 flags |= Service.START_FLAG_RETRY;
1916 }
1917 if (si.doneExecutingCount > 0) {
1918 flags |= Service.START_FLAG_REDELIVERY;
1919 }
1920 r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001921 } catch (TransactionTooLargeException e) {
1922 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Transaction too large: intent="
1923 + si.intent);
1924 caughtException = e;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001925 } catch (RemoteException e) {
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001926 // Remote process gone... we'll let the normal cleanup take care of this.
1927 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Crashed while sending args: " + r);
1928 caughtException = e;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001929 } catch (Exception e) {
1930 Slog.w(TAG, "Unexpected exception", e);
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07001931 caughtException = e;
1932 }
1933
1934 if (caughtException != null) {
1935 // Keep nesting count correct
1936 final boolean inDestroying = mDestroyingServices.contains(r);
1937 serviceDoneExecutingLocked(r, inDestroying, inDestroying);
1938 if (caughtException instanceof TransactionTooLargeException) {
1939 throw (TransactionTooLargeException)caughtException;
1940 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001941 break;
1942 }
1943 }
1944 }
1945
Dianne Hackborn164371f2013-10-01 19:10:13 -07001946 private final boolean isServiceNeeded(ServiceRecord r, boolean knowConn, boolean hasConn) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001947 // Are we still explicitly being asked to run?
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001948 if (r.startRequested) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001949 return true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001950 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001951
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001952 // Is someone still bound to us keepign us running?
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001953 if (!knowConn) {
1954 hasConn = r.hasAutoCreateConnections();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001955 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001956 if (hasConn) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07001957 return true;
1958 }
1959
1960 return false;
1961 }
1962
1963 private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
1964 boolean hasConn) {
1965 //Slog.i(TAG, "Bring down service:");
1966 //r.dump(" ");
1967
1968 if (isServiceNeeded(r, knowConn, hasConn)) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001969 return;
1970 }
1971
Dianne Hackborn9210bc82013-09-05 12:31:16 -07001972 // Are we in the process of launching?
1973 if (mPendingServices.contains(r)) {
1974 return;
1975 }
1976
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001977 bringDownServiceLocked(r);
1978 }
1979
1980 private final void bringDownServiceLocked(ServiceRecord r) {
1981 //Slog.i(TAG, "Bring down service:");
1982 //r.dump(" ");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07001983
Dianne Hackborn390517b2013-05-30 15:03:32 -07001984 // Report to all of the connections that the service is no longer
1985 // available.
1986 for (int conni=r.connections.size()-1; conni>=0; conni--) {
1987 ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
1988 for (int i=0; i<c.size(); i++) {
1989 ConnectionRecord cr = c.get(i);
1990 // There is still a connection to the service that is
1991 // being brought down. Mark it as dead.
1992 cr.serviceDead = true;
1993 try {
1994 cr.conn.connected(r.name, null);
1995 } catch (Exception e) {
1996 Slog.w(TAG, "Failure disconnecting service " + r.name +
1997 " to connection " + c.get(i).conn.asBinder() +
1998 " (in " + c.get(i).binding.client.processName + ")", e);
1999 }
2000 }
2001 }
2002
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002003 // Tell the service that it has been unbound.
Dianne Hackborn390517b2013-05-30 15:03:32 -07002004 if (r.app != null && r.app.thread != null) {
2005 for (int i=r.bindings.size()-1; i>=0; i--) {
2006 IntentBindRecord ibr = r.bindings.valueAt(i);
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002007 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing down binding " + ibr
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002008 + ": hasBound=" + ibr.hasBound);
Dianne Hackborn390517b2013-05-30 15:03:32 -07002009 if (ibr.hasBound) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002010 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002011 bumpServiceExecutingLocked(r, false, "bring down unbind");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002012 mAm.updateOomAdjLocked(r.app);
2013 ibr.hasBound = false;
2014 r.app.thread.scheduleUnbindService(r,
2015 ibr.intent.getIntent());
2016 } catch (Exception e) {
2017 Slog.w(TAG, "Exception when unbinding service "
2018 + r.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07002019 serviceProcessGoneLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002020 }
2021 }
2022 }
2023 }
2024
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002025 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bringing down " + r + " " + r.intent);
Craig Mautner66c4a822015-01-16 12:48:16 -08002026 r.destroyTime = SystemClock.uptimeMillis();
Dianne Hackbornf85e7af2014-10-14 10:43:43 -07002027 if (LOG_SERVICE_START_STOP) {
2028 EventLogTags.writeAmDestroyService(
2029 r.userId, System.identityHashCode(r), (r.app != null) ? r.app.pid : -1);
2030 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002031
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002032 final ServiceMap smap = getServiceMap(r.userId);
2033 smap.mServicesByName.remove(r.name);
2034 smap.mServicesByIntent.remove(r.intent);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002035 r.totalRestartCount = 0;
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08002036 unscheduleServiceRestartLocked(r, 0, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002037
2038 // Also make sure it is not on the pending list.
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08002039 for (int i=mPendingServices.size()-1; i>=0; i--) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002040 if (mPendingServices.get(i) == r) {
2041 mPendingServices.remove(i);
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002042 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Removed pending: " + r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002043 }
2044 }
2045
Dianne Hackborn0ba4c712016-08-01 17:49:41 -07002046 cancelForegroudNotificationLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002047 r.isForeground = false;
2048 r.foregroundId = 0;
2049 r.foregroundNoti = null;
2050
2051 // Clear start entries.
2052 r.clearDeliveredStartsLocked();
2053 r.pendingStarts.clear();
2054
2055 if (r.app != null) {
2056 synchronized (r.stats.getBatteryStats()) {
2057 r.stats.stopLaunchedLocked();
2058 }
2059 r.app.services.remove(r);
Dianne Hackborna590d2b2016-06-27 15:07:18 -07002060 if (r.whitelistManager) {
2061 updateWhitelistManagerLocked(r.app);
2062 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002063 if (r.app.thread != null) {
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002064 updateServiceForegroundLocked(r.app, false);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002065 try {
Dianne Hackborn164371f2013-10-01 19:10:13 -07002066 bumpServiceExecutingLocked(r, false, "destroy");
2067 mDestroyingServices.add(r);
Dianne Hackborn455625e2015-01-21 09:55:13 -08002068 r.destroying = true;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002069 mAm.updateOomAdjLocked(r.app);
2070 r.app.thread.scheduleStopService(r);
2071 } catch (Exception e) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07002072 Slog.w(TAG, "Exception when destroying service "
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002073 + r.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07002074 serviceProcessGoneLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002075 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002076 } else {
2077 if (DEBUG_SERVICE) Slog.v(
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002078 TAG_SERVICE, "Removed service that has no process: " + r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002079 }
2080 } else {
2081 if (DEBUG_SERVICE) Slog.v(
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002082 TAG_SERVICE, "Removed service that is not running: " + r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002083 }
2084
2085 if (r.bindings.size() > 0) {
2086 r.bindings.clear();
2087 }
2088
2089 if (r.restarter instanceof ServiceRestarter) {
2090 ((ServiceRestarter)r.restarter).setService(null);
2091 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002092
Dianne Hackbornd2932242013-08-05 18:18:42 -07002093 int memFactor = mAm.mProcessStats.getMemFactorLocked();
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002094 long now = SystemClock.uptimeMillis();
2095 if (r.tracker != null) {
2096 r.tracker.setStarted(false, memFactor, now);
2097 r.tracker.setBound(false, memFactor, now);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07002098 if (r.executeNesting == 0) {
Dianne Hackborn878deb32013-10-14 16:55:09 -07002099 r.tracker.clearCurrentOwner(r, false);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07002100 r.tracker = null;
2101 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002102 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002103
2104 smap.ensureNotStartingBackground(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002105 }
2106
2107 void removeConnectionLocked(
2108 ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
2109 IBinder binder = c.conn.asBinder();
2110 AppBindRecord b = c.binding;
2111 ServiceRecord s = b.service;
2112 ArrayList<ConnectionRecord> clist = s.connections.get(binder);
2113 if (clist != null) {
2114 clist.remove(c);
2115 if (clist.size() == 0) {
2116 s.connections.remove(binder);
2117 }
2118 }
2119 b.connections.remove(c);
2120 if (c.activity != null && c.activity != skipAct) {
2121 if (c.activity.connections != null) {
2122 c.activity.connections.remove(c);
2123 }
2124 }
2125 if (b.client != skipApp) {
2126 b.client.connections.remove(c);
2127 if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
2128 b.client.updateHasAboveClientLocked();
2129 }
Dianne Hackborna590d2b2016-06-27 15:07:18 -07002130 // If this connection requested whitelist management, see if we should
2131 // now clear that state.
2132 if ((c.flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
2133 s.updateWhitelistManager();
2134 if (!s.whitelistManager && s.app != null) {
2135 updateWhitelistManagerLocked(s.app);
2136 }
2137 }
Dianne Hackborndb926082013-10-31 16:32:44 -07002138 if (s.app != null) {
Dianne Hackborn465fa392014-09-14 14:21:18 -07002139 updateServiceClientActivitiesLocked(s.app, c, true);
Dianne Hackborndb926082013-10-31 16:32:44 -07002140 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002141 }
2142 clist = mServiceConnections.get(binder);
2143 if (clist != null) {
2144 clist.remove(c);
2145 if (clist.size() == 0) {
2146 mServiceConnections.remove(binder);
2147 }
2148 }
2149
Dianne Hackbornab2df062015-01-07 13:43:13 -08002150 mAm.stopAssociationLocked(b.client.uid, b.client.processName, s.appInfo.uid, s.name);
2151
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002152 if (b.connections.size() == 0) {
2153 b.intent.apps.remove(b.client);
2154 }
2155
2156 if (!c.serviceDead) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002157 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Disconnecting binding " + b.intent
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002158 + ": shouldUnbind=" + b.intent.hasBound);
2159 if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
2160 && b.intent.hasBound) {
2161 try {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002162 bumpServiceExecutingLocked(s, false, "unbind");
Dianne Hackborndb926082013-10-31 16:32:44 -07002163 if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0
2164 && s.app.setProcState <= ActivityManager.PROCESS_STATE_RECEIVER) {
2165 // If this service's process is not already in the cached list,
2166 // then update it in the LRU list here because this may be causing
2167 // it to go down there and we want it to start out near the top.
2168 mAm.updateLruProcessLocked(s.app, false, null);
2169 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002170 mAm.updateOomAdjLocked(s.app);
2171 b.intent.hasBound = false;
2172 // Assume the client doesn't want to know about a rebind;
2173 // we will deal with that later if it asks for one.
2174 b.intent.doRebind = false;
2175 s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
2176 } catch (Exception e) {
2177 Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
Dianne Hackborn878deb32013-10-14 16:55:09 -07002178 serviceProcessGoneLocked(s);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002179 }
2180 }
2181
Svet Ganov9c165d72015-12-01 19:52:26 -08002182 // If unbound while waiting to start, remove the pending service
2183 mPendingServices.remove(s);
2184
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002185 if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002186 boolean hasAutoCreate = s.hasAutoCreateConnections();
2187 if (!hasAutoCreate) {
2188 if (s.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07002189 s.tracker.setBound(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002190 SystemClock.uptimeMillis());
2191 }
2192 }
2193 bringDownServiceIfNeededLocked(s, true, hasAutoCreate);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002194 }
2195 }
2196 }
2197
2198 void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07002199 boolean inDestroying = mDestroyingServices.contains(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002200 if (r != null) {
Dianne Hackborn455625e2015-01-21 09:55:13 -08002201 if (type == ActivityThread.SERVICE_DONE_EXECUTING_START) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002202 // This is a call from a service start... take care of
2203 // book-keeping.
2204 r.callStart = true;
2205 switch (res) {
2206 case Service.START_STICKY_COMPATIBILITY:
2207 case Service.START_STICKY: {
2208 // We are done with the associated start arguments.
2209 r.findDeliveredStart(startId, true);
2210 // Don't stop if killed.
2211 r.stopIfKilled = false;
2212 break;
2213 }
2214 case Service.START_NOT_STICKY: {
2215 // We are done with the associated start arguments.
2216 r.findDeliveredStart(startId, true);
2217 if (r.getLastStartId() == startId) {
2218 // There is no more work, and this service
2219 // doesn't want to hang around if killed.
2220 r.stopIfKilled = true;
2221 }
2222 break;
2223 }
2224 case Service.START_REDELIVER_INTENT: {
2225 // We'll keep this item until they explicitly
2226 // call stop for it, but keep track of the fact
2227 // that it was delivered.
2228 ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
2229 if (si != null) {
2230 si.deliveryCount = 0;
2231 si.doneExecutingCount++;
2232 // Don't stop if killed.
2233 r.stopIfKilled = true;
2234 }
2235 break;
2236 }
2237 case Service.START_TASK_REMOVED_COMPLETE: {
2238 // Special processing for onTaskRemoved(). Don't
2239 // impact normal onStartCommand() processing.
2240 r.findDeliveredStart(startId, true);
2241 break;
2242 }
2243 default:
2244 throw new IllegalArgumentException(
2245 "Unknown service start result: " + res);
2246 }
2247 if (res == Service.START_STICKY_COMPATIBILITY) {
2248 r.callStart = false;
2249 }
Dianne Hackborn455625e2015-01-21 09:55:13 -08002250 } else if (type == ActivityThread.SERVICE_DONE_EXECUTING_STOP) {
2251 // This is the final call from destroying the service... we should
2252 // actually be getting rid of the service at this point. Do some
2253 // validation of its state, and ensure it will be fully removed.
2254 if (!inDestroying) {
2255 // Not sure what else to do with this... if it is not actually in the
2256 // destroying list, we don't need to make sure to remove it from it.
Amith Yamasanid0418222016-05-10 15:49:51 -07002257 // If the app is null, then it was probably removed because the process died,
2258 // otherwise wtf
2259 if (r.app != null) {
Joe Onorato9d97ee22016-05-31 10:49:08 -07002260 Slog.w(TAG, "Service done with onDestroy, but not inDestroying: "
Amith Yamasanid0418222016-05-10 15:49:51 -07002261 + r + ", app=" + r.app);
2262 }
Dianne Hackborn455625e2015-01-21 09:55:13 -08002263 } else if (r.executeNesting != 1) {
Joe Onorato9d97ee22016-05-31 10:49:08 -07002264 Slog.w(TAG, "Service done with onDestroy, but executeNesting="
Dianne Hackborn455625e2015-01-21 09:55:13 -08002265 + r.executeNesting + ": " + r);
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07002266 // Fake it to keep from ANR due to orphaned entry.
Dianne Hackborn455625e2015-01-21 09:55:13 -08002267 r.executeNesting = 1;
2268 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002269 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002270 final long origId = Binder.clearCallingIdentity();
Dianne Hackborn164371f2013-10-01 19:10:13 -07002271 serviceDoneExecutingLocked(r, inDestroying, inDestroying);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002272 Binder.restoreCallingIdentity(origId);
2273 } else {
2274 Slog.w(TAG, "Done executing unknown service from pid "
2275 + Binder.getCallingPid());
2276 }
2277 }
2278
Dianne Hackborn878deb32013-10-14 16:55:09 -07002279 private void serviceProcessGoneLocked(ServiceRecord r) {
2280 if (r.tracker != null) {
2281 int memFactor = mAm.mProcessStats.getMemFactorLocked();
2282 long now = SystemClock.uptimeMillis();
2283 r.tracker.setExecuting(false, memFactor, now);
2284 r.tracker.setBound(false, memFactor, now);
Dianne Hackbornbc72dce2013-11-11 10:43:38 -08002285 r.tracker.setStarted(false, memFactor, now);
Dianne Hackborn878deb32013-10-14 16:55:09 -07002286 }
2287 serviceDoneExecutingLocked(r, true, true);
2288 }
2289
Dianne Hackborn164371f2013-10-01 19:10:13 -07002290 private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
2291 boolean finishing) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002292 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "<<< DONE EXECUTING " + r
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002293 + ": nesting=" + r.executeNesting
Dianne Hackborn164371f2013-10-01 19:10:13 -07002294 + ", inDestroying=" + inDestroying + ", app=" + r.app);
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002295 else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,
2296 "<<< DONE EXECUTING " + r.shortName);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002297 r.executeNesting--;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002298 if (r.executeNesting <= 0) {
2299 if (r.app != null) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002300 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002301 "Nesting at 0 of " + r.shortName);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002302 r.app.execServicesFg = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002303 r.app.executingServices.remove(r);
2304 if (r.app.executingServices.size() == 0) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002305 if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG_SERVICE_EXECUTING,
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002306 "No more executingServices of " + r.shortName);
2307 mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002308 } else if (r.executeFg) {
2309 // Need to re-evaluate whether the app still needs to be in the foreground.
2310 for (int i=r.app.executingServices.size()-1; i>=0; i--) {
2311 if (r.app.executingServices.valueAt(i).executeFg) {
2312 r.app.execServicesFg = true;
2313 break;
2314 }
2315 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002316 }
Dianne Hackborn164371f2013-10-01 19:10:13 -07002317 if (inDestroying) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002318 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
Dianne Hackborn164371f2013-10-01 19:10:13 -07002319 "doneExecuting remove destroying " + r);
2320 mDestroyingServices.remove(r);
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002321 r.bindings.clear();
2322 }
2323 mAm.updateOomAdjLocked(r.app);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002324 }
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002325 r.executeFg = false;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002326 if (r.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07002327 r.tracker.setExecuting(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002328 SystemClock.uptimeMillis());
Dianne Hackborn164371f2013-10-01 19:10:13 -07002329 if (finishing) {
Dianne Hackborn878deb32013-10-14 16:55:09 -07002330 r.tracker.clearCurrentOwner(r, false);
Dianne Hackbornbd754f42013-07-23 15:52:36 -07002331 r.tracker = null;
2332 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002333 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002334 if (finishing) {
Dianne Hackborn90e9b1d2013-11-21 12:50:01 -08002335 if (r.app != null && !r.app.persistent) {
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002336 r.app.services.remove(r);
Dianne Hackborna590d2b2016-06-27 15:07:18 -07002337 if (r.whitelistManager) {
2338 updateWhitelistManagerLocked(r.app);
2339 }
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002340 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002341 r.app = null;
2342 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002343 }
2344 }
2345
Dianne Hackbornff072722014-09-24 10:56:28 -07002346 boolean attachApplicationLocked(ProcessRecord proc, String processName)
2347 throws RemoteException {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002348 boolean didSomething = false;
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07002349 // Collect any services that are waiting for this process to come up.
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002350 if (mPendingServices.size() > 0) {
2351 ServiceRecord sr = null;
2352 try {
2353 for (int i=0; i<mPendingServices.size(); i++) {
2354 sr = mPendingServices.get(i);
2355 if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
2356 || !processName.equals(sr.processName))) {
2357 continue;
2358 }
2359
2360 mPendingServices.remove(i);
2361 i--;
Dianne Hackbornf7097a52014-05-13 09:56:14 -07002362 proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,
2363 mAm.mProcessStats);
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002364 realStartServiceLocked(sr, proc, sr.createdFromFg);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002365 didSomething = true;
Dianne Hackborn865907d2015-10-21 17:12:53 -07002366 if (!isServiceNeeded(sr, false, false)) {
2367 // We were waiting for this service to start, but it is actually no
2368 // longer needed. This could happen because bringDownServiceIfNeeded
2369 // won't bring down a service that is pending... so now the pending
2370 // is done, so let's drop it.
2371 bringDownServiceLocked(sr);
2372 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002373 }
Dianne Hackbornff072722014-09-24 10:56:28 -07002374 } catch (RemoteException e) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002375 Slog.w(TAG, "Exception in new application when starting service "
2376 + sr.shortName, e);
2377 throw e;
2378 }
2379 }
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07002380 // Also, if there are any services that are waiting to restart and
2381 // would run in this process, now is a good time to start them. It would
2382 // be weird to bring up the process but arbitrarily not let the services
2383 // run at this point just because their restart time hasn't come up.
2384 if (mRestartingServices.size() > 0) {
Dianne Hackborn865907d2015-10-21 17:12:53 -07002385 ServiceRecord sr;
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07002386 for (int i=0; i<mRestartingServices.size(); i++) {
2387 sr = mRestartingServices.get(i);
2388 if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
2389 || !processName.equals(sr.processName))) {
2390 continue;
2391 }
2392 mAm.mHandler.removeCallbacks(sr.restarter);
2393 mAm.mHandler.post(sr.restarter);
2394 }
2395 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002396 return didSomething;
2397 }
2398
2399 void processStartTimedOutLocked(ProcessRecord proc) {
2400 for (int i=0; i<mPendingServices.size(); i++) {
2401 ServiceRecord sr = mPendingServices.get(i);
2402 if ((proc.uid == sr.appInfo.uid
2403 && proc.processName.equals(sr.processName))
2404 || sr.isolatedProc == proc) {
2405 Slog.w(TAG, "Forcing bringing down service: " + sr);
2406 sr.isolatedProc = null;
2407 mPendingServices.remove(i);
2408 i--;
Dianne Hackborn91268cf2013-06-13 19:06:50 -07002409 bringDownServiceLocked(sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002410 }
2411 }
2412 }
2413
Wale Ogunwale540e1232015-05-01 15:35:39 -07002414 private boolean collectPackageServicesLocked(String packageName, Set<String> filterByClasses,
Wale Ogunwale2cb2dd42015-09-02 14:53:29 -07002415 boolean evenPersistent, boolean doit, boolean killProcess,
2416 ArrayMap<ComponentName, ServiceRecord> services) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002417 boolean didSomething = false;
Wale Ogunwale540e1232015-05-01 15:35:39 -07002418 for (int i = services.size() - 1; i >= 0; i--) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002419 ServiceRecord service = services.valueAt(i);
Wale Ogunwale540e1232015-05-01 15:35:39 -07002420 final boolean sameComponent = packageName == null
2421 || (service.packageName.equals(packageName)
2422 && (filterByClasses == null
2423 || filterByClasses.contains(service.name.getClassName())));
2424 if (sameComponent
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002425 && (service.app == null || evenPersistent || !service.app.persistent)) {
2426 if (!doit) {
2427 return true;
2428 }
2429 didSomething = true;
2430 Slog.i(TAG, " Force stopping service " + service);
2431 if (service.app != null) {
Wale Ogunwale2cb2dd42015-09-02 14:53:29 -07002432 service.app.removed = killProcess;
Dianne Hackborn90e9b1d2013-11-21 12:50:01 -08002433 if (!service.app.persistent) {
2434 service.app.services.remove(service);
Dianne Hackborna590d2b2016-06-27 15:07:18 -07002435 if (service.whitelistManager) {
2436 updateWhitelistManagerLocked(service.app);
2437 }
Dianne Hackborn90e9b1d2013-11-21 12:50:01 -08002438 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002439 }
2440 service.app = null;
2441 service.isolatedProc = null;
Wale Ogunwale540e1232015-05-01 15:35:39 -07002442 if (mTmpCollectionResults == null) {
2443 mTmpCollectionResults = new ArrayList<>();
2444 }
2445 mTmpCollectionResults.add(service);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002446 }
2447 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07002448 return didSomething;
2449 }
2450
Wale Ogunwale540e1232015-05-01 15:35:39 -07002451 boolean bringDownDisabledPackageServicesLocked(String packageName, Set<String> filterByClasses,
Wale Ogunwale2cb2dd42015-09-02 14:53:29 -07002452 int userId, boolean evenPersistent, boolean killProcess, boolean doit) {
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07002453 boolean didSomething = false;
Wale Ogunwale540e1232015-05-01 15:35:39 -07002454
2455 if (mTmpCollectionResults != null) {
2456 mTmpCollectionResults.clear();
2457 }
2458
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07002459 if (userId == UserHandle.USER_ALL) {
Wale Ogunwale540e1232015-05-01 15:35:39 -07002460 for (int i = mServiceMap.size() - 1; i >= 0; i--) {
2461 didSomething |= collectPackageServicesLocked(packageName, filterByClasses,
Wale Ogunwale2cb2dd42015-09-02 14:53:29 -07002462 evenPersistent, doit, killProcess, mServiceMap.valueAt(i).mServicesByName);
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07002463 if (!doit && didSomething) {
2464 return true;
2465 }
2466 }
2467 } else {
Amith Yamasani540b6592013-10-01 13:02:52 -07002468 ServiceMap smap = mServiceMap.get(userId);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002469 if (smap != null) {
2470 ArrayMap<ComponentName, ServiceRecord> items = smap.mServicesByName;
Wale Ogunwale540e1232015-05-01 15:35:39 -07002471 didSomething = collectPackageServicesLocked(packageName, filterByClasses,
Wale Ogunwale2cb2dd42015-09-02 14:53:29 -07002472 evenPersistent, doit, killProcess, items);
Dianne Hackborn2d1b3782012-09-09 17:49:39 -07002473 }
Dianne Hackborn5e03e2c2012-09-06 14:21:19 -07002474 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002475
Wale Ogunwale540e1232015-05-01 15:35:39 -07002476 if (mTmpCollectionResults != null) {
2477 for (int i = mTmpCollectionResults.size() - 1; i >= 0; i--) {
2478 bringDownServiceLocked(mTmpCollectionResults.get(i));
2479 }
2480 mTmpCollectionResults.clear();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002481 }
2482 return didSomething;
2483 }
2484
2485 void cleanUpRemovedTaskLocked(TaskRecord tr, ComponentName component, Intent baseIntent) {
Wale Ogunwale540e1232015-05-01 15:35:39 -07002486 ArrayList<ServiceRecord> services = new ArrayList<>();
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002487 ArrayMap<ComponentName, ServiceRecord> alls = getServices(tr.userId);
Wale Ogunwale540e1232015-05-01 15:35:39 -07002488 for (int i = alls.size() - 1; i >= 0; i--) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002489 ServiceRecord sr = alls.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002490 if (sr.packageName.equals(component.getPackageName())) {
2491 services.add(sr);
2492 }
2493 }
2494
2495 // Take care of any running services associated with the app.
Wale Ogunwale540e1232015-05-01 15:35:39 -07002496 for (int i = services.size() - 1; i >= 0; i--) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002497 ServiceRecord sr = services.get(i);
2498 if (sr.startRequested) {
2499 if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
2500 Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
2501 stopServiceLocked(sr);
2502 } else {
2503 sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
2504 sr.makeNextStartId(), baseIntent, null));
2505 if (sr.app != null && sr.app.thread != null) {
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002506 // We always run in the foreground, since this is called as
2507 // part of the "remove task" UI operation.
Craig Mautner5f2bb4c2015-03-12 16:10:27 -07002508 try {
2509 sendServiceArgsLocked(sr, true, false);
2510 } catch (TransactionTooLargeException e) {
2511 // Ignore, keep going.
2512 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002513 }
2514 }
2515 }
2516 }
2517 }
2518
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002519 final void killServicesLocked(ProcessRecord app, boolean allowRestart) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002520 // Report disconnected services.
2521 if (false) {
2522 // XXX we are letting the client link to the service for
2523 // death notifications.
2524 if (app.services.size() > 0) {
2525 Iterator<ServiceRecord> it = app.services.iterator();
2526 while (it.hasNext()) {
2527 ServiceRecord r = it.next();
Dianne Hackborn390517b2013-05-30 15:03:32 -07002528 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2529 ArrayList<ConnectionRecord> cl = r.connections.valueAt(conni);
2530 for (int i=0; i<cl.size(); i++) {
2531 ConnectionRecord c = cl.get(i);
2532 if (c.binding.client != app) {
2533 try {
2534 //c.conn.connected(r.className, null);
2535 } catch (Exception e) {
2536 // todo: this should be asynchronous!
2537 Slog.w(TAG, "Exception thrown disconnected servce "
2538 + r.shortName
2539 + " from app " + app.processName, e);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002540 }
2541 }
2542 }
2543 }
2544 }
2545 }
2546 }
2547
louis_chang40e259c2015-03-26 13:31:14 +08002548 // Clean up any connections this application has to other services.
2549 for (int i = app.connections.size() - 1; i >= 0; i--) {
2550 ConnectionRecord r = app.connections.valueAt(i);
2551 removeConnectionLocked(r, app, null);
2552 }
2553 updateServiceConnectionActivitiesLocked(app);
2554 app.connections.clear();
2555
Dianne Hackborna590d2b2016-06-27 15:07:18 -07002556 app.whitelistManager = false;
2557
louis_chang40e259c2015-03-26 13:31:14 +08002558 // Clear app state from services.
2559 for (int i = app.services.size() - 1; i >= 0; i--) {
Dianne Hackbornc8230512013-07-13 21:32:12 -07002560 ServiceRecord sr = app.services.valueAt(i);
2561 synchronized (sr.stats.getBatteryStats()) {
2562 sr.stats.stopLaunchedLocked();
2563 }
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08002564 if (sr.app != app && sr.app != null && !sr.app.persistent) {
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002565 sr.app.services.remove(sr);
2566 }
Dianne Hackbornc8230512013-07-13 21:32:12 -07002567 sr.app = null;
2568 sr.isolatedProc = null;
2569 sr.executeNesting = 0;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002570 sr.forceClearTracker();
2571 if (mDestroyingServices.remove(sr)) {
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002572 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "killServices remove destroying " + sr);
Dianne Hackbornc8230512013-07-13 21:32:12 -07002573 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002574
Dianne Hackbornc8230512013-07-13 21:32:12 -07002575 final int numClients = sr.bindings.size();
2576 for (int bindingi=numClients-1; bindingi>=0; bindingi--) {
2577 IntentBindRecord b = sr.bindings.valueAt(bindingi);
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002578 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Killing binding " + b
Dianne Hackbornc8230512013-07-13 21:32:12 -07002579 + ": shouldUnbind=" + b.hasBound);
2580 b.binder = null;
2581 b.requested = b.received = b.hasBound = false;
Dianne Hackborn465fa392014-09-14 14:21:18 -07002582 // If this binding is coming from a cached process and is asking to keep
2583 // the service created, then we'll kill the cached process as well -- we
2584 // don't want to be thrashing around restarting processes that are only
2585 // there to be cached.
2586 for (int appi=b.apps.size()-1; appi>=0; appi--) {
Dianne Hackborn24c98e82014-09-14 17:23:54 -07002587 final ProcessRecord proc = b.apps.keyAt(appi);
2588 // If the process is already gone, skip it.
2589 if (proc.killedByAm || proc.thread == null) {
2590 continue;
2591 }
2592 // Only do this for processes that have an auto-create binding;
2593 // otherwise the binding can be left, because it won't cause the
2594 // service to restart.
2595 final AppBindRecord abind = b.apps.valueAt(appi);
2596 boolean hasCreate = false;
2597 for (int conni=abind.connections.size()-1; conni>=0; conni--) {
2598 ConnectionRecord conn = abind.connections.valueAt(conni);
Dianne Hackborn0fe3c252014-09-19 15:09:39 -07002599 if ((conn.flags&(Context.BIND_AUTO_CREATE|Context.BIND_ALLOW_OOM_MANAGEMENT
2600 |Context.BIND_WAIVE_PRIORITY)) == Context.BIND_AUTO_CREATE) {
Dianne Hackborn24c98e82014-09-14 17:23:54 -07002601 hasCreate = true;
2602 break;
2603 }
2604 }
2605 if (!hasCreate) {
2606 continue;
2607 }
Dianne Hackborncd97c962014-09-25 18:34:02 -07002608 // XXX turned off for now until we have more time to get a better policy.
2609 if (false && proc != null && !proc.persistent && proc.thread != null
Dianne Hackborn465fa392014-09-14 14:21:18 -07002610 && proc.pid != 0 && proc.pid != ActivityManagerService.MY_PID
2611 && proc.setProcState >= ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
2612 proc.kill("bound to service " + sr.name.flattenToShortString()
2613 + " in dying proc " + (app != null ? app.processName : "??"), true);
2614 }
2615 }
Dianne Hackbornc8230512013-07-13 21:32:12 -07002616 }
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002617 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002618
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002619 ServiceMap smap = getServiceMap(app.userId);
2620
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002621 // Now do remaining service cleanup.
2622 for (int i=app.services.size()-1; i>=0; i--) {
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002623 ServiceRecord sr = app.services.valueAt(i);
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08002624
2625 // Unless the process is persistent, this process record is going away,
2626 // so make sure the service is cleaned out of it.
2627 if (!app.persistent) {
Dianne Hackborn4190fc52013-12-09 18:20:16 -08002628 app.services.removeAt(i);
Dianne Hackbornaa9875e2013-12-09 11:26:11 -08002629 }
2630
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002631 // Sanity check: if the service listed for the app is not one
Dianne Hackborn4190fc52013-12-09 18:20:16 -08002632 // we actually are maintaining, just let it drop.
Dianne Hackborn40c87252014-03-19 16:55:40 -07002633 final ServiceRecord curRec = smap.mServicesByName.get(sr.name);
2634 if (curRec != sr) {
2635 if (curRec != null) {
2636 Slog.wtf(TAG, "Service " + sr + " in process " + app
2637 + " not same as in map: " + curRec);
2638 }
Dianne Hackbornddc19e92013-11-14 14:32:17 -08002639 continue;
2640 }
2641
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002642 // Any services running in the application may need to be placed
2643 // back in the pending list.
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002644 if (allowRestart && sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
Dianne Hackbornc8230512013-07-13 21:32:12 -07002645 &ApplicationInfo.FLAG_PERSISTENT) == 0) {
2646 Slog.w(TAG, "Service crashed " + sr.crashCount
2647 + " times, stopping: " + sr);
2648 EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
2649 sr.userId, sr.crashCount, sr.shortName, app.pid);
2650 bringDownServiceLocked(sr);
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07002651 } else if (!allowRestart
Jeff Sharkeye17ac152015-11-06 22:40:29 -08002652 || !mAm.mUserController.isUserRunningLocked(sr.userId, 0)) {
Dianne Hackbornc8230512013-07-13 21:32:12 -07002653 bringDownServiceLocked(sr);
2654 } else {
2655 boolean canceled = scheduleServiceRestartLocked(sr, true);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002656
Dianne Hackbornc8230512013-07-13 21:32:12 -07002657 // Should the service remain running? Note that in the
2658 // extreme case of so many attempts to deliver a command
2659 // that it failed we also will stop it here.
2660 if (sr.startRequested && (sr.stopIfKilled || canceled)) {
2661 if (sr.pendingStarts.size() == 0) {
2662 sr.startRequested = false;
2663 if (sr.tracker != null) {
Dianne Hackbornd2932242013-08-05 18:18:42 -07002664 sr.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
Dianne Hackbornc8230512013-07-13 21:32:12 -07002665 SystemClock.uptimeMillis());
2666 }
2667 if (!sr.hasAutoCreateConnections()) {
2668 // Whoops, no reason to restart!
2669 bringDownServiceLocked(sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002670 }
2671 }
2672 }
2673 }
Dianne Hackbornc8230512013-07-13 21:32:12 -07002674 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002675
Dianne Hackbornc8230512013-07-13 21:32:12 -07002676 if (!allowRestart) {
2677 app.services.clear();
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002678
2679 // Make sure there are no more restarting services for this process.
2680 for (int i=mRestartingServices.size()-1; i>=0; i--) {
2681 ServiceRecord r = mRestartingServices.get(i);
2682 if (r.processName.equals(app.processName) &&
2683 r.serviceInfo.applicationInfo.uid == app.info.uid) {
2684 mRestartingServices.remove(i);
Dianne Hackbornd6f5b622013-11-11 17:25:37 -08002685 clearRestartingIfNeededLocked(r);
2686 }
2687 }
2688 for (int i=mPendingServices.size()-1; i>=0; i--) {
2689 ServiceRecord r = mPendingServices.get(i);
2690 if (r.processName.equals(app.processName) &&
2691 r.serviceInfo.applicationInfo.uid == app.info.uid) {
2692 mPendingServices.remove(i);
Dianne Hackborndaa0d5c2013-11-06 16:30:29 -08002693 }
2694 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002695 }
2696
2697 // Make sure we have no more records on the stopping list.
Dianne Hackborn164371f2013-10-01 19:10:13 -07002698 int i = mDestroyingServices.size();
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002699 while (i > 0) {
2700 i--;
Dianne Hackborn164371f2013-10-01 19:10:13 -07002701 ServiceRecord sr = mDestroyingServices.get(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002702 if (sr.app == app) {
Dianne Hackborn164371f2013-10-01 19:10:13 -07002703 sr.forceClearTracker();
2704 mDestroyingServices.remove(i);
Wale Ogunwaled57969f2014-11-15 19:37:29 -08002705 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "killServices remove destroying " + sr);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002706 }
2707 }
2708
2709 app.executingServices.clear();
2710 }
2711
2712 ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
2713 ActivityManager.RunningServiceInfo info =
2714 new ActivityManager.RunningServiceInfo();
2715 info.service = r.name;
2716 if (r.app != null) {
2717 info.pid = r.app.pid;
2718 }
2719 info.uid = r.appInfo.uid;
2720 info.process = r.processName;
2721 info.foreground = r.isForeground;
2722 info.activeSince = r.createTime;
2723 info.started = r.startRequested;
2724 info.clientCount = r.connections.size();
2725 info.crashCount = r.crashCount;
2726 info.lastActivityTime = r.lastActivity;
2727 if (r.isForeground) {
2728 info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
2729 }
2730 if (r.startRequested) {
2731 info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
2732 }
2733 if (r.app != null && r.app.pid == ActivityManagerService.MY_PID) {
2734 info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
2735 }
2736 if (r.app != null && r.app.persistent) {
2737 info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
2738 }
2739
Dianne Hackborn390517b2013-05-30 15:03:32 -07002740 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2741 ArrayList<ConnectionRecord> connl = r.connections.valueAt(conni);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002742 for (int i=0; i<connl.size(); i++) {
2743 ConnectionRecord conn = connl.get(i);
2744 if (conn.clientLabel != 0) {
2745 info.clientPackage = conn.binding.client.info.packageName;
2746 info.clientLabel = conn.clientLabel;
2747 return info;
2748 }
2749 }
2750 }
2751 return info;
2752 }
2753
2754 List<ActivityManager.RunningServiceInfo> getRunningServiceInfoLocked(int maxNum,
2755 int flags) {
2756 ArrayList<ActivityManager.RunningServiceInfo> res
2757 = new ArrayList<ActivityManager.RunningServiceInfo>();
2758
Dianne Hackborn0c380492012-08-20 17:23:30 -07002759 final int uid = Binder.getCallingUid();
2760 final long ident = Binder.clearCallingIdentity();
2761 try {
2762 if (ActivityManager.checkUidPermission(
2763 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2764 uid) == PackageManager.PERMISSION_GRANTED) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07002765 int[] users = mAm.mUserController.getUsers();
Dianne Hackborn1676c852012-09-10 14:52:30 -07002766 for (int ui=0; ui<users.length && res.size() < maxNum; ui++) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002767 ArrayMap<ComponentName, ServiceRecord> alls = getServices(users[ui]);
2768 for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
2769 ServiceRecord sr = alls.valueAt(i);
2770 res.add(makeRunningServiceInfoLocked(sr));
Dianne Hackborn0c380492012-08-20 17:23:30 -07002771 }
2772 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002773
Dianne Hackborn0c380492012-08-20 17:23:30 -07002774 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
2775 ServiceRecord r = mRestartingServices.get(i);
2776 ActivityManager.RunningServiceInfo info =
2777 makeRunningServiceInfoLocked(r);
2778 info.restarting = r.nextRestartTime;
2779 res.add(info);
2780 }
2781 } else {
2782 int userId = UserHandle.getUserId(uid);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002783 ArrayMap<ComponentName, ServiceRecord> alls = getServices(userId);
2784 for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
2785 ServiceRecord sr = alls.valueAt(i);
2786 res.add(makeRunningServiceInfoLocked(sr));
Dianne Hackborn0c380492012-08-20 17:23:30 -07002787 }
2788
2789 for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
2790 ServiceRecord r = mRestartingServices.get(i);
2791 if (r.userId == userId) {
2792 ActivityManager.RunningServiceInfo info =
2793 makeRunningServiceInfoLocked(r);
2794 info.restarting = r.nextRestartTime;
2795 res.add(info);
2796 }
2797 }
2798 }
2799 } finally {
2800 Binder.restoreCallingIdentity(ident);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002801 }
2802
2803 return res;
2804 }
2805
2806 public PendingIntent getRunningServiceControlPanelLocked(ComponentName name) {
Dianne Hackbornf02b60a2012-08-16 10:48:27 -07002807 int userId = UserHandle.getUserId(Binder.getCallingUid());
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002808 ServiceRecord r = getServiceByName(name, userId);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002809 if (r != null) {
Dianne Hackborn390517b2013-05-30 15:03:32 -07002810 for (int conni=r.connections.size()-1; conni>=0; conni--) {
2811 ArrayList<ConnectionRecord> conn = r.connections.valueAt(conni);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002812 for (int i=0; i<conn.size(); i++) {
2813 if (conn.get(i).clientIntent != null) {
2814 return conn.get(i).clientIntent;
2815 }
2816 }
2817 }
2818 }
2819 return null;
2820 }
2821
2822 void serviceTimeout(ProcessRecord proc) {
2823 String anrMessage = null;
2824
Dianne Hackbornc2f6f942014-09-22 13:36:42 -07002825 synchronized(mAm) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002826 if (proc.executingServices.size() == 0 || proc.thread == null) {
2827 return;
2828 }
Dianne Hackbornab2df062015-01-07 13:43:13 -08002829 final long now = SystemClock.uptimeMillis();
2830 final long maxTime = now -
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002831 (proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002832 ServiceRecord timeout = null;
2833 long nextTime = 0;
Dianne Hackbornc8230512013-07-13 21:32:12 -07002834 for (int i=proc.executingServices.size()-1; i>=0; i--) {
2835 ServiceRecord sr = proc.executingServices.valueAt(i);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002836 if (sr.executingStart < maxTime) {
2837 timeout = sr;
2838 break;
2839 }
2840 if (sr.executingStart > nextTime) {
2841 nextTime = sr.executingStart;
2842 }
2843 }
2844 if (timeout != null && mAm.mLruProcesses.contains(proc)) {
2845 Slog.w(TAG, "Timeout executing service: " + timeout);
Dianne Hackborncff1bbf2015-01-20 13:43:32 -08002846 StringWriter sw = new StringWriter();
2847 PrintWriter pw = new FastPrintWriter(sw, false, 1024);
2848 pw.println(timeout);
2849 timeout.dump(pw, " ");
2850 pw.close();
2851 mLastAnrDump = sw.toString();
2852 mAm.mHandler.removeCallbacks(mLastAnrDumpClearer);
2853 mAm.mHandler.postDelayed(mLastAnrDumpClearer, LAST_ANR_LIFETIME_DURATION_MSECS);
2854 anrMessage = "executing service " + timeout.shortName;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002855 } else {
2856 Message msg = mAm.mHandler.obtainMessage(
2857 ActivityManagerService.SERVICE_TIMEOUT_MSG);
2858 msg.obj = proc;
Dianne Hackbornbf36ee22013-07-26 18:24:10 -07002859 mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg
Dianne Hackborn2be00932013-09-22 16:46:00 -07002860 ? (nextTime+SERVICE_TIMEOUT) : (nextTime + SERVICE_BACKGROUND_TIMEOUT));
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002861 }
2862 }
2863
2864 if (anrMessage != null) {
Adrian Roos20d7df32016-01-12 18:59:43 +01002865 mAm.mAppErrors.appNotResponding(proc, null, null, false, anrMessage);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002866 }
2867 }
2868
Dianne Hackborn2be00932013-09-22 16:46:00 -07002869 void scheduleServiceTimeoutLocked(ProcessRecord proc) {
2870 if (proc.executingServices.size() == 0 || proc.thread == null) {
2871 return;
2872 }
2873 long now = SystemClock.uptimeMillis();
2874 Message msg = mAm.mHandler.obtainMessage(
2875 ActivityManagerService.SERVICE_TIMEOUT_MSG);
2876 msg.obj = proc;
2877 mAm.mHandler.sendMessageAtTime(msg,
2878 proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
2879 }
2880
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002881 /**
2882 * Prints a list of ServiceRecords (dumpsys activity services)
2883 */
Dianne Hackborn777a06d2016-05-16 17:36:15 -07002884 List<ServiceRecord> collectServicesToDumpLocked(ItemMatcher matcher, String dumpPackage) {
2885 final ArrayList<ServiceRecord> services = new ArrayList<>();
2886 final int[] users = mAm.mUserController.getUsers();
2887 for (int user : users) {
2888 ServiceMap smap = getServiceMap(user);
2889 if (smap.mServicesByName.size() > 0) {
2890 for (int si=0; si<smap.mServicesByName.size(); si++) {
2891 ServiceRecord r = smap.mServicesByName.valueAt(si);
2892 if (!matcher.match(r, r.name)) {
2893 continue;
2894 }
2895 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2896 continue;
2897 }
2898 services.add(r);
2899 }
Dianne Hackborncff1bbf2015-01-20 13:43:32 -08002900 }
Dianne Hackborn777a06d2016-05-16 17:36:15 -07002901 }
2902
2903 return services;
2904 }
2905
2906 final class ServiceDumper {
2907 private final FileDescriptor fd;
2908 private final PrintWriter pw;
2909 private final String[] args;
2910 private final int opti;
2911 private final boolean dumpAll;
2912 private final String dumpPackage;
2913 private final ItemMatcher matcher;
2914 private final ArrayList<ServiceRecord> services = new ArrayList<>();
2915
2916 private final long nowReal = SystemClock.elapsedRealtime();
2917
2918 private boolean needSep = false;
2919 private boolean printedAnything = false;
2920 private boolean printed = false;
2921
2922 /**
2923 * Note: do not call directly, use {@link #newServiceDumperLocked} instead (this
2924 * must be called with the lock held).
2925 */
2926 ServiceDumper(FileDescriptor fd, PrintWriter pw, String[] args,
2927 int opti, boolean dumpAll, String dumpPackage) {
2928 this.fd = fd;
2929 this.pw = pw;
2930 this.args = args;
2931 this.opti = opti;
2932 this.dumpAll = dumpAll;
2933 this.dumpPackage = dumpPackage;
2934 matcher = new ItemMatcher();
2935 matcher.build(args, opti);
2936
2937 final int[] users = mAm.mUserController.getUsers();
Dianne Hackborn1676c852012-09-10 14:52:30 -07002938 for (int user : users) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002939 ServiceMap smap = getServiceMap(user);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002940 if (smap.mServicesByName.size() > 0) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07002941 for (int si=0; si<smap.mServicesByName.size(); si++) {
2942 ServiceRecord r = smap.mServicesByName.valueAt(si);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002943 if (!matcher.match(r, r.name)) {
2944 continue;
2945 }
2946 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2947 continue;
2948 }
Dianne Hackborn777a06d2016-05-16 17:36:15 -07002949 services.add(r);
2950 }
2951 }
2952 }
2953 }
2954
2955 private void dumpHeaderLocked() {
2956 pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
2957 if (mLastAnrDump != null) {
2958 pw.println(" Last ANR service:");
2959 pw.print(mLastAnrDump);
2960 pw.println();
2961 }
2962 }
2963
2964 void dumpLocked() {
2965 dumpHeaderLocked();
2966
2967 try {
2968 int[] users = mAm.mUserController.getUsers();
2969 for (int user : users) {
2970 // Find the first service for this user.
2971 int serviceIdx = 0;
2972 while (serviceIdx < services.size() && services.get(serviceIdx).userId != user) {
2973 serviceIdx++;
2974 }
2975 printed = false;
2976 if (serviceIdx < services.size()) {
2977 needSep = false;
2978 while (serviceIdx < services.size()) {
2979 ServiceRecord r = services.get(serviceIdx);
2980 serviceIdx++;
2981 if (r.userId != user) {
2982 break;
Dianne Hackbornf88dd0b2012-08-08 17:20:32 -07002983 }
Dianne Hackborn777a06d2016-05-16 17:36:15 -07002984 dumpServiceLocalLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07002985 }
Dianne Hackborn777a06d2016-05-16 17:36:15 -07002986 needSep |= printed;
2987 }
2988
2989 dumpUserRemainsLocked(user);
2990 }
2991 } catch (Exception e) {
2992 Slog.w(TAG, "Exception in dumpServicesLocked", e);
2993 }
2994
2995 dumpRemainsLocked();
2996 }
2997
2998 void dumpWithClient() {
2999 synchronized(mAm) {
3000 dumpHeaderLocked();
3001 }
3002
3003 try {
3004 int[] users = mAm.mUserController.getUsers();
3005 for (int user : users) {
3006 // Find the first service for this user.
3007 int serviceIdx = 0;
3008 while (serviceIdx < services.size() && services.get(serviceIdx).userId != user) {
3009 serviceIdx++;
3010 }
3011 printed = false;
3012 if (serviceIdx < services.size()) {
3013 needSep = false;
3014 while (serviceIdx < services.size()) {
3015 ServiceRecord r = services.get(serviceIdx);
3016 serviceIdx++;
3017 if (r.userId != user) {
3018 break;
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003019 }
Dianne Hackborn777a06d2016-05-16 17:36:15 -07003020 synchronized(mAm) {
3021 dumpServiceLocalLocked(r);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003022 }
Dianne Hackborn777a06d2016-05-16 17:36:15 -07003023 dumpServiceClient(r);
3024 }
3025 needSep |= printed;
3026 }
3027
3028 synchronized(mAm) {
3029 dumpUserRemainsLocked(user);
3030 }
3031 }
3032 } catch (Exception e) {
3033 Slog.w(TAG, "Exception in dumpServicesLocked", e);
3034 }
3035
3036 synchronized(mAm) {
3037 dumpRemainsLocked();
3038 }
3039 }
3040
3041 private void dumpUserHeaderLocked(int user) {
3042 if (!printed) {
3043 if (printedAnything) {
3044 pw.println();
3045 }
3046 pw.println(" User " + user + " active services:");
3047 printed = true;
3048 }
3049 printedAnything = true;
3050 if (needSep) {
3051 pw.println();
3052 }
3053 }
3054
3055 private void dumpServiceLocalLocked(ServiceRecord r) {
3056 dumpUserHeaderLocked(r.userId);
3057 pw.print(" * ");
3058 pw.println(r);
3059 if (dumpAll) {
3060 r.dump(pw, " ");
3061 needSep = true;
3062 } else {
3063 pw.print(" app=");
3064 pw.println(r.app);
3065 pw.print(" created=");
3066 TimeUtils.formatDuration(r.createTime, nowReal, pw);
3067 pw.print(" started=");
3068 pw.print(r.startRequested);
3069 pw.print(" connections=");
3070 pw.println(r.connections.size());
3071 if (r.connections.size() > 0) {
3072 pw.println(" Connections:");
3073 for (int conni=0; conni<r.connections.size(); conni++) {
3074 ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
3075 for (int i = 0; i < clist.size(); i++) {
3076 ConnectionRecord conn = clist.get(i);
3077 pw.print(" ");
3078 pw.print(conn.binding.intent.intent.getIntent()
3079 .toShortString(false, false, false, false));
3080 pw.print(" -> ");
3081 ProcessRecord proc = conn.binding.client;
3082 pw.println(proc != null ? proc.toShortString() : "null");
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003083 }
3084 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003085 }
Dianne Hackborn777a06d2016-05-16 17:36:15 -07003086 }
3087 }
3088
3089 private void dumpServiceClient(ServiceRecord r) {
3090 final ProcessRecord proc = r.app;
3091 if (proc == null) {
3092 return;
3093 }
3094 final IApplicationThread thread = proc.thread;
3095 if (thread == null) {
3096 return;
3097 }
3098 pw.println(" Client:");
3099 pw.flush();
3100 try {
3101 TransferPipe tp = new TransferPipe();
3102 try {
3103 thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
3104 tp.setBufferPrefix(" ");
3105 // Short timeout, since blocking here can
3106 // deadlock with the application.
3107 tp.go(fd, 2000);
3108 } finally {
3109 tp.kill();
3110 }
3111 } catch (IOException e) {
3112 pw.println(" Failure while dumping the service: " + e);
3113 } catch (RemoteException e) {
3114 pw.println(" Got a RemoteException while dumping the service");
3115 }
3116 needSep = true;
3117 }
3118
3119 private void dumpUserRemainsLocked(int user) {
3120 ServiceMap smap = getServiceMap(user);
3121 printed = false;
3122 for (int si=0, SN=smap.mDelayedStartList.size(); si<SN; si++) {
3123 ServiceRecord r = smap.mDelayedStartList.get(si);
3124 if (!matcher.match(r, r.name)) {
3125 continue;
3126 }
3127 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
3128 continue;
3129 }
3130 if (!printed) {
3131 if (printedAnything) {
3132 pw.println();
3133 }
3134 pw.println(" User " + user + " delayed start services:");
3135 printed = true;
3136 }
3137 printedAnything = true;
3138 pw.print(" * Delayed start "); pw.println(r);
3139 }
3140 printed = false;
3141 for (int si=0, SN=smap.mStartingBackground.size(); si<SN; si++) {
3142 ServiceRecord r = smap.mStartingBackground.get(si);
3143 if (!matcher.match(r, r.name)) {
3144 continue;
3145 }
3146 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
3147 continue;
3148 }
3149 if (!printed) {
3150 if (printedAnything) {
3151 pw.println();
3152 }
3153 pw.println(" User " + user + " starting in background:");
3154 printed = true;
3155 }
3156 printedAnything = true;
3157 pw.print(" * Starting bg "); pw.println(r);
3158 }
3159 }
3160
3161 private void dumpRemainsLocked() {
3162 if (mPendingServices.size() > 0) {
Dianne Hackborn9210bc82013-09-05 12:31:16 -07003163 printed = false;
Dianne Hackborn777a06d2016-05-16 17:36:15 -07003164 for (int i=0; i<mPendingServices.size(); i++) {
3165 ServiceRecord r = mPendingServices.get(i);
Dianne Hackborn9210bc82013-09-05 12:31:16 -07003166 if (!matcher.match(r, r.name)) {
3167 continue;
3168 }
3169 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
3170 continue;
3171 }
Dianne Hackborn9210bc82013-09-05 12:31:16 -07003172 printedAnything = true;
3173 if (!printed) {
3174 if (needSep) pw.println();
3175 needSep = true;
Dianne Hackborn777a06d2016-05-16 17:36:15 -07003176 pw.println(" Pending services:");
Dianne Hackborn9210bc82013-09-05 12:31:16 -07003177 printed = true;
3178 }
Dianne Hackborn777a06d2016-05-16 17:36:15 -07003179 pw.print(" * Pending "); pw.println(r);
3180 r.dump(pw, " ");
3181 }
3182 needSep = true;
3183 }
3184
3185 if (mRestartingServices.size() > 0) {
3186 printed = false;
3187 for (int i=0; i<mRestartingServices.size(); i++) {
3188 ServiceRecord r = mRestartingServices.get(i);
3189 if (!matcher.match(r, r.name)) {
3190 continue;
3191 }
3192 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
3193 continue;
3194 }
3195 printedAnything = true;
3196 if (!printed) {
3197 if (needSep) pw.println();
3198 needSep = true;
3199 pw.println(" Restarting services:");
3200 printed = true;
3201 }
3202 pw.print(" * Restarting "); pw.println(r);
3203 r.dump(pw, " ");
3204 }
3205 needSep = true;
3206 }
3207
3208 if (mDestroyingServices.size() > 0) {
3209 printed = false;
3210 for (int i=0; i< mDestroyingServices.size(); i++) {
3211 ServiceRecord r = mDestroyingServices.get(i);
3212 if (!matcher.match(r, r.name)) {
3213 continue;
3214 }
3215 if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
3216 continue;
3217 }
3218 printedAnything = true;
3219 if (!printed) {
3220 if (needSep) pw.println();
3221 needSep = true;
3222 pw.println(" Destroying services:");
3223 printed = true;
3224 }
3225 pw.print(" * Destroy "); pw.println(r);
3226 r.dump(pw, " ");
3227 }
3228 needSep = true;
3229 }
3230
3231 if (dumpAll) {
3232 printed = false;
3233 for (int ic=0; ic<mServiceConnections.size(); ic++) {
3234 ArrayList<ConnectionRecord> r = mServiceConnections.valueAt(ic);
3235 for (int i=0; i<r.size(); i++) {
3236 ConnectionRecord cr = r.get(i);
3237 if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
3238 continue;
3239 }
3240 if (dumpPackage != null && (cr.binding.client == null
3241 || !dumpPackage.equals(cr.binding.client.info.packageName))) {
3242 continue;
3243 }
3244 printedAnything = true;
3245 if (!printed) {
3246 if (needSep) pw.println();
3247 needSep = true;
3248 pw.println(" Connection bindings to services:");
3249 printed = true;
3250 }
3251 pw.print(" * "); pw.println(cr);
3252 cr.dump(pw, " ");
3253 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003254 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003255 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003256
Dianne Hackborn777a06d2016-05-16 17:36:15 -07003257 if (!printedAnything) {
3258 pw.println(" (nothing)");
3259 }
Dianne Hackborn7ad34e52013-06-05 18:41:45 -07003260 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003261 }
3262
Dianne Hackborn777a06d2016-05-16 17:36:15 -07003263 ServiceDumper newServiceDumperLocked(FileDescriptor fd, PrintWriter pw, String[] args,
3264 int opti, boolean dumpAll, String dumpPackage) {
3265 return new ServiceDumper(fd, pw, args, opti, dumpAll, dumpPackage);
3266 }
3267
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003268 /**
3269 * There are three ways to call this:
3270 * - no service specified: dump all the services
3271 * - a flattened component name that matched an existing service was specified as the
3272 * first arg: dump that one service
3273 * - the first arg isn't the flattened component name of an existing service:
3274 * dump all services whose component contains the first arg as a substring
3275 */
3276 protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
3277 int opti, boolean dumpAll) {
3278 ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
3279
Dianne Hackbornc2f6f942014-09-22 13:36:42 -07003280 synchronized (mAm) {
Fyodor Kupolovf63b89c2015-10-27 18:08:56 -07003281 int[] users = mAm.mUserController.getUsers();
Dianne Hackborn1676c852012-09-10 14:52:30 -07003282 if ("all".equals(name)) {
3283 for (int user : users) {
Dianne Hackborn13c590d2013-10-07 14:32:00 -07003284 ServiceMap smap = mServiceMap.get(user);
3285 if (smap == null) {
3286 continue;
3287 }
3288 ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07003289 for (int i=0; i<alls.size(); i++) {
3290 ServiceRecord r1 = alls.valueAt(i);
Amith Yamasani258848d2012-08-10 17:06:33 -07003291 services.add(r1);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003292 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003293 }
Dianne Hackborn1676c852012-09-10 14:52:30 -07003294 } else {
3295 ComponentName componentName = name != null
3296 ? ComponentName.unflattenFromString(name) : null;
3297 int objectId = 0;
3298 if (componentName == null) {
3299 // Not a '/' separated full component name; maybe an object ID?
3300 try {
3301 objectId = Integer.parseInt(name, 16);
3302 name = null;
3303 componentName = null;
3304 } catch (RuntimeException e) {
3305 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003306 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003307
Dianne Hackborn1676c852012-09-10 14:52:30 -07003308 for (int user : users) {
Dianne Hackborn13c590d2013-10-07 14:32:00 -07003309 ServiceMap smap = mServiceMap.get(user);
3310 if (smap == null) {
3311 continue;
3312 }
3313 ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
Dianne Hackborn9210bc82013-09-05 12:31:16 -07003314 for (int i=0; i<alls.size(); i++) {
3315 ServiceRecord r1 = alls.valueAt(i);
Amith Yamasani258848d2012-08-10 17:06:33 -07003316 if (componentName != null) {
3317 if (r1.name.equals(componentName)) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003318 services.add(r1);
3319 }
Amith Yamasani258848d2012-08-10 17:06:33 -07003320 } else if (name != null) {
3321 if (r1.name.flattenToString().contains(name)) {
3322 services.add(r1);
3323 }
3324 } else if (System.identityHashCode(r1) == objectId) {
3325 services.add(r1);
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003326 }
3327 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003328 }
3329 }
3330 }
3331
3332 if (services.size() <= 0) {
3333 return false;
3334 }
3335
3336 boolean needSep = false;
3337 for (int i=0; i<services.size(); i++) {
3338 if (needSep) {
3339 pw.println();
3340 }
3341 needSep = true;
3342 dumpService("", fd, pw, services.get(i), args, dumpAll);
3343 }
3344 return true;
3345 }
3346
3347 /**
3348 * Invokes IApplicationThread.dumpService() on the thread of the specified service if
3349 * there is a thread associated with the service.
3350 */
3351 private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
3352 final ServiceRecord r, String[] args, boolean dumpAll) {
3353 String innerPrefix = prefix + " ";
Dianne Hackbornc2f6f942014-09-22 13:36:42 -07003354 synchronized (mAm) {
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003355 pw.print(prefix); pw.print("SERVICE ");
3356 pw.print(r.shortName); pw.print(" ");
3357 pw.print(Integer.toHexString(System.identityHashCode(r)));
3358 pw.print(" pid=");
3359 if (r.app != null) pw.println(r.app.pid);
3360 else pw.println("(not running)");
3361 if (dumpAll) {
3362 r.dump(pw, innerPrefix);
3363 }
3364 }
3365 if (r.app != null && r.app.thread != null) {
3366 pw.print(prefix); pw.println(" Client:");
3367 pw.flush();
3368 try {
3369 TransferPipe tp = new TransferPipe();
3370 try {
3371 r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
3372 tp.setBufferPrefix(prefix + " ");
3373 tp.go(fd);
3374 } finally {
3375 tp.kill();
3376 }
3377 } catch (IOException e) {
3378 pw.println(prefix + " Failure while dumping the service: " + e);
3379 } catch (RemoteException e) {
3380 pw.println(prefix + " Got a RemoteException while dumping the service");
3381 }
3382 }
3383 }
Dianne Hackborn599db5c2012-08-03 19:28:48 -07003384}