1/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.server.am;
18
19import java.io.FileDescriptor;
20import java.io.IOException;
21import java.io.PrintWriter;
22import java.io.StringWriter;
23import java.util.ArrayList;
24import java.util.HashSet;
25import java.util.Iterator;
26import java.util.List;
27
28import android.app.ActivityThread;
29import android.os.Build;
30import android.os.DeadObjectException;
31import android.os.Handler;
32import android.os.Looper;
33import android.os.SystemProperties;
34import android.util.ArrayMap;
35import android.util.ArraySet;
36import com.android.internal.app.ProcessStats;
37import com.android.internal.os.BatteryStatsImpl;
38import com.android.internal.os.TransferPipe;
39import com.android.internal.util.FastPrintWriter;
40import com.android.server.am.ActivityManagerService.ItemMatcher;
41import com.android.server.am.ActivityManagerService.NeededUriGrants;
42
43import android.app.ActivityManager;
44import android.app.AppGlobals;
45import android.app.IApplicationThread;
46import android.app.IServiceConnection;
47import android.app.Notification;
48import android.app.PendingIntent;
49import android.app.Service;
50import android.content.ComponentName;
51import android.content.Context;
52import android.content.Intent;
53import android.content.pm.ApplicationInfo;
54import android.content.pm.PackageManager;
55import android.content.pm.ResolveInfo;
56import android.content.pm.ServiceInfo;
57import android.os.Binder;
58import android.os.IBinder;
59import android.os.Message;
60import android.os.Process;
61import android.os.RemoteException;
62import android.os.SystemClock;
63import android.os.UserHandle;
64import android.util.EventLog;
65import android.util.Slog;
66import android.util.SparseArray;
67import android.util.TimeUtils;
68
69public final class ActiveServices {
70    static final boolean DEBUG_SERVICE = ActivityManagerService.DEBUG_SERVICE;
71    static final boolean DEBUG_SERVICE_EXECUTING = ActivityManagerService.DEBUG_SERVICE_EXECUTING;
72    static final boolean DEBUG_DELAYED_SERVICE = ActivityManagerService.DEBUG_SERVICE;
73    static final boolean DEBUG_DELAYED_STARTS = DEBUG_DELAYED_SERVICE;
74    static final boolean DEBUG_MU = ActivityManagerService.DEBUG_MU;
75    static final boolean LOG_SERVICE_START_STOP = false;
76    static final String TAG = ActivityManagerService.TAG;
77    static final String TAG_MU = ActivityManagerService.TAG_MU;
78
79    // How long we wait for a service to finish executing.
80    static final int SERVICE_TIMEOUT = 20*1000;
81
82    // How long we wait for a service to finish executing.
83    static final int SERVICE_BACKGROUND_TIMEOUT = SERVICE_TIMEOUT * 10;
84
85    // How long a service needs to be running until restarting its process
86    // is no longer considered to be a relaunch of the service.
87    static final int SERVICE_RESTART_DURATION = 1*1000;
88
89    // How long a service needs to be running until it will start back at
90    // SERVICE_RESTART_DURATION after being killed.
91    static final int SERVICE_RESET_RUN_DURATION = 60*1000;
92
93    // Multiplying factor to increase restart duration time by, for each time
94    // a service is killed before it has run for SERVICE_RESET_RUN_DURATION.
95    static final int SERVICE_RESTART_DURATION_FACTOR = 4;
96
97    // The minimum amount of time between restarting services that we allow.
98    // That is, when multiple services are restarting, we won't allow each
99    // to restart less than this amount of time from the last one.
100    static final int SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000;
101
102    // Maximum amount of time for there to be no activity on a service before
103    // we consider it non-essential and allow its process to go on the
104    // LRU background list.
105    static final int MAX_SERVICE_INACTIVITY = 30*60*1000;
106
107    // How long we wait for a background started service to stop itself before
108    // allowing the next pending start to run.
109    static final int BG_START_TIMEOUT = 15*1000;
110
111    final ActivityManagerService mAm;
112
113    // Maximum number of services that we allow to start in the background
114    // at the same time.
115    final int mMaxStartingBackground;
116
117    final SparseArray<ServiceMap> mServiceMap = new SparseArray<ServiceMap>();
118
119    /**
120     * All currently bound service connections.  Keys are the IBinder of
121     * the client's IServiceConnection.
122     */
123    final ArrayMap<IBinder, ArrayList<ConnectionRecord>> mServiceConnections
124            = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>();
125
126    /**
127     * List of services that we have been asked to start,
128     * but haven't yet been able to.  It is used to hold start requests
129     * while waiting for their corresponding application thread to get
130     * going.
131     */
132    final ArrayList<ServiceRecord> mPendingServices
133            = new ArrayList<ServiceRecord>();
134
135    /**
136     * List of services that are scheduled to restart following a crash.
137     */
138    final ArrayList<ServiceRecord> mRestartingServices
139            = new ArrayList<ServiceRecord>();
140
141    /**
142     * List of services that are in the process of being destroyed.
143     */
144    final ArrayList<ServiceRecord> mDestroyingServices
145            = new ArrayList<ServiceRecord>();
146
147    /** Amount of time to allow a last ANR message to exist before freeing the memory. */
148    static final int LAST_ANR_LIFETIME_DURATION_MSECS = 2 * 60 * 60 * 1000; // Two hours
149
150    String mLastAnrDump;
151
152    final Runnable mLastAnrDumpClearer = new Runnable() {
153        @Override public void run() {
154            synchronized (mAm) {
155                mLastAnrDump = null;
156            }
157        }
158    };
159
160    static final class DelayingProcess extends ArrayList<ServiceRecord> {
161        long timeoout;
162    }
163
164    /**
165     * Information about services for a single user.
166     */
167    class ServiceMap extends Handler {
168        final int mUserId;
169        final ArrayMap<ComponentName, ServiceRecord> mServicesByName
170                = new ArrayMap<ComponentName, ServiceRecord>();
171        final ArrayMap<Intent.FilterComparison, ServiceRecord> mServicesByIntent
172                = new ArrayMap<Intent.FilterComparison, ServiceRecord>();
173
174        final ArrayList<ServiceRecord> mDelayedStartList
175                = new ArrayList<ServiceRecord>();
176        /* XXX eventually I'd like to have this based on processes instead of services.
177         * That is, if we try to start two services in a row both running in the same
178         * process, this should be one entry in mStartingBackground for that one process
179         * that remains until all services in it are done.
180        final ArrayMap<ProcessRecord, DelayingProcess> mStartingBackgroundMap
181                = new ArrayMap<ProcessRecord, DelayingProcess>();
182        final ArrayList<DelayingProcess> mStartingProcessList
183                = new ArrayList<DelayingProcess>();
184        */
185
186        final ArrayList<ServiceRecord> mStartingBackground
187                = new ArrayList<ServiceRecord>();
188
189        static final int MSG_BG_START_TIMEOUT = 1;
190
191        ServiceMap(Looper looper, int userId) {
192            super(looper);
193            mUserId = userId;
194        }
195
196        @Override
197        public void handleMessage(Message msg) {
198            switch (msg.what) {
199                case MSG_BG_START_TIMEOUT: {
200                    synchronized (mAm) {
201                        rescheduleDelayedStarts();
202                    }
203                } break;
204            }
205        }
206
207        void ensureNotStartingBackground(ServiceRecord r) {
208            if (mStartingBackground.remove(r)) {
209                if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "No longer background starting: " + r);
210                rescheduleDelayedStarts();
211            }
212            if (mDelayedStartList.remove(r)) {
213                if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "No longer delaying start: " + r);
214            }
215        }
216
217        void rescheduleDelayedStarts() {
218            removeMessages(MSG_BG_START_TIMEOUT);
219            final long now = SystemClock.uptimeMillis();
220            for (int i=0, N=mStartingBackground.size(); i<N; i++) {
221                ServiceRecord r = mStartingBackground.get(i);
222                if (r.startingBgTimeout <= now) {
223                    Slog.i(TAG, "Waited long enough for: " + r);
224                    mStartingBackground.remove(i);
225                    N--;
226                    i--;
227                }
228            }
229            while (mDelayedStartList.size() > 0
230                    && mStartingBackground.size() < mMaxStartingBackground) {
231                ServiceRecord r = mDelayedStartList.remove(0);
232                if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "REM FR DELAY LIST (exec next): " + r);
233                if (r.pendingStarts.size() <= 0) {
234                    Slog.w(TAG, "**** NO PENDING STARTS! " + r + " startReq=" + r.startRequested
235                            + " delayedStop=" + r.delayedStop);
236                }
237                if (DEBUG_DELAYED_SERVICE) {
238                    if (mDelayedStartList.size() > 0) {
239                        Slog.v(TAG, "Remaining delayed list:");
240                        for (int i=0; i<mDelayedStartList.size(); i++) {
241                            Slog.v(TAG, "  #" + i + ": " + mDelayedStartList.get(i));
242                        }
243                    }
244                }
245                r.delayed = false;
246                startServiceInnerLocked(this, r.pendingStarts.get(0).intent, r, false, true);
247            }
248            if (mStartingBackground.size() > 0) {
249                ServiceRecord next = mStartingBackground.get(0);
250                long when = next.startingBgTimeout > now ? next.startingBgTimeout : now;
251                if (DEBUG_DELAYED_SERVICE) Slog.v(TAG, "Top bg start is " + next
252                        + ", can delay others up to " + when);
253                Message msg = obtainMessage(MSG_BG_START_TIMEOUT);
254                sendMessageAtTime(msg, when);
255            }
256            if (mStartingBackground.size() < mMaxStartingBackground) {
257                mAm.backgroundServicesFinishedLocked(mUserId);
258            }
259        }
260    }
261
262    public ActiveServices(ActivityManagerService service) {
263        mAm = service;
264        int maxBg = 0;
265        try {
266            maxBg = Integer.parseInt(SystemProperties.get("ro.config.max_starting_bg", "0"));
267        } catch(RuntimeException e) {
268        }
269        mMaxStartingBackground = maxBg > 0
270                ? maxBg : ActivityManager.isLowRamDeviceStatic() ? 1 : 8;
271    }
272
273    ServiceRecord getServiceByName(ComponentName name, int callingUser) {
274        // TODO: Deal with global services
275        if (DEBUG_MU)
276            Slog.v(TAG_MU, "getServiceByName(" + name + "), callingUser = " + callingUser);
277        return getServiceMap(callingUser).mServicesByName.get(name);
278    }
279
280    boolean hasBackgroundServices(int callingUser) {
281        ServiceMap smap = mServiceMap.get(callingUser);
282        return smap != null ? smap.mStartingBackground.size() >= mMaxStartingBackground : false;
283    }
284
285    private ServiceMap getServiceMap(int callingUser) {
286        ServiceMap smap = mServiceMap.get(callingUser);
287        if (smap == null) {
288            smap = new ServiceMap(mAm.mHandler.getLooper(), callingUser);
289            mServiceMap.put(callingUser, smap);
290        }
291        return smap;
292    }
293
294    ArrayMap<ComponentName, ServiceRecord> getServices(int callingUser) {
295        return getServiceMap(callingUser).mServicesByName;
296    }
297
298    ComponentName startServiceLocked(IApplicationThread caller,
299            Intent service, String resolvedType,
300            int callingPid, int callingUid, int userId) {
301        if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "startService: " + service
302                + " type=" + resolvedType + " args=" + service.getExtras());
303
304        final boolean callerFg;
305        if (caller != null) {
306            final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
307            if (callerApp == null) {
308                throw new SecurityException(
309                        "Unable to find app for caller " + caller
310                        + " (pid=" + Binder.getCallingPid()
311                        + ") when starting service " + service);
312            }
313            callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
314        } else {
315            callerFg = true;
316        }
317
318
319        ServiceLookupResult res =
320            retrieveServiceLocked(service, resolvedType,
321                    callingPid, callingUid, userId, true, callerFg);
322        if (res == null) {
323            return null;
324        }
325        if (res.record == null) {
326            return new ComponentName("!", res.permission != null
327                    ? res.permission : "private to package");
328        }
329
330        ServiceRecord r = res.record;
331
332        if (!mAm.getUserManagerLocked().exists(r.userId)) {
333            Slog.d(TAG, "Trying to start service with non-existent user! " + r.userId);
334            return null;
335        }
336
337        NeededUriGrants neededGrants = mAm.checkGrantUriPermissionFromIntentLocked(
338                callingUid, r.packageName, service, service.getFlags(), null, r.userId);
339        if (unscheduleServiceRestartLocked(r, callingUid, false)) {
340            if (DEBUG_SERVICE) Slog.v(TAG, "START SERVICE WHILE RESTART PENDING: " + r);
341        }
342        r.lastActivity = SystemClock.uptimeMillis();
343        r.startRequested = true;
344        r.delayedStop = false;
345        r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
346                service, neededGrants));
347
348        final ServiceMap smap = getServiceMap(r.userId);
349        boolean addToStarting = false;
350        if (!callerFg && r.app == null && mAm.mStartedUsers.get(r.userId) != null) {
351            ProcessRecord proc = mAm.getProcessRecordLocked(r.processName, r.appInfo.uid, false);
352            if (proc == null || proc.curProcState > ActivityManager.PROCESS_STATE_RECEIVER) {
353                // If this is not coming from a foreground caller, then we may want
354                // to delay the start if there are already other background services
355                // that are starting.  This is to avoid process start spam when lots
356                // of applications are all handling things like connectivity broadcasts.
357                // We only do this for cached processes, because otherwise an application
358                // can have assumptions about calling startService() for a service to run
359                // in its own process, and for that process to not be killed before the
360                // service is started.  This is especially the case for receivers, which
361                // may start a service in onReceive() to do some additional work and have
362                // initialized some global state as part of that.
363                if (DEBUG_DELAYED_SERVICE) Slog.v(TAG, "Potential start delay of " + r + " in "
364                        + proc);
365                if (r.delayed) {
366                    // This service is already scheduled for a delayed start; just leave
367                    // it still waiting.
368                    if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Continuing to delay: " + r);
369                    return r.name;
370                }
371                if (smap.mStartingBackground.size() >= mMaxStartingBackground) {
372                    // Something else is starting, delay!
373                    Slog.i(TAG, "Delaying start of: " + r);
374                    smap.mDelayedStartList.add(r);
375                    r.delayed = true;
376                    return r.name;
377                }
378                if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Not delaying: " + r);
379                addToStarting = true;
380            } else if (proc.curProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
381                // We slightly loosen when we will enqueue this new service as a background
382                // starting service we are waiting for, to also include processes that are
383                // currently running other services or receivers.
384                addToStarting = true;
385                if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Not delaying, but counting as bg: " + r);
386            } else if (DEBUG_DELAYED_STARTS) {
387                StringBuilder sb = new StringBuilder(128);
388                sb.append("Not potential delay (state=").append(proc.curProcState)
389                        .append(' ').append(proc.adjType);
390                String reason = proc.makeAdjReason();
391                if (reason != null) {
392                    sb.append(' ');
393                    sb.append(reason);
394                }
395                sb.append("): ");
396                sb.append(r.toString());
397                Slog.v(TAG, sb.toString());
398            }
399        } else if (DEBUG_DELAYED_STARTS) {
400            if (callerFg) {
401                Slog.v(TAG, "Not potential delay (callerFg=" + callerFg + " uid="
402                        + callingUid + " pid=" + callingPid + "): " + r);
403            } else if (r.app != null) {
404                Slog.v(TAG, "Not potential delay (cur app=" + r.app + "): " + r);
405            } else {
406                Slog.v(TAG, "Not potential delay (user " + r.userId + " not started): " + r);
407            }
408        }
409
410        return startServiceInnerLocked(smap, service, r, callerFg, addToStarting);
411    }
412
413    ComponentName startServiceInnerLocked(ServiceMap smap, Intent service,
414            ServiceRecord r, boolean callerFg, boolean addToStarting) {
415        ProcessStats.ServiceState stracker = r.getTracker();
416        if (stracker != null) {
417            stracker.setStarted(true, mAm.mProcessStats.getMemFactorLocked(), r.lastActivity);
418        }
419        r.callStart = false;
420        synchronized (r.stats.getBatteryStats()) {
421            r.stats.startRunningLocked();
422        }
423        String error = bringUpServiceLocked(r, service.getFlags(), callerFg, false);
424        if (error != null) {
425            return new ComponentName("!!", error);
426        }
427
428        if (r.startRequested && addToStarting) {
429            boolean first = smap.mStartingBackground.size() == 0;
430            smap.mStartingBackground.add(r);
431            r.startingBgTimeout = SystemClock.uptimeMillis() + BG_START_TIMEOUT;
432            if (DEBUG_DELAYED_SERVICE) {
433                RuntimeException here = new RuntimeException("here");
434                here.fillInStackTrace();
435                Slog.v(TAG, "Starting background (first=" + first + "): " + r, here);
436            } else if (DEBUG_DELAYED_STARTS) {
437                Slog.v(TAG, "Starting background (first=" + first + "): " + r);
438            }
439            if (first) {
440                smap.rescheduleDelayedStarts();
441            }
442        } else if (callerFg) {
443            smap.ensureNotStartingBackground(r);
444        }
445
446        return r.name;
447    }
448
449    private void stopServiceLocked(ServiceRecord service) {
450        if (service.delayed) {
451            // If service isn't actually running, but is is being held in the
452            // delayed list, then we need to keep it started but note that it
453            // should be stopped once no longer delayed.
454            if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Delaying stop of pending: " + service);
455            service.delayedStop = true;
456            return;
457        }
458        synchronized (service.stats.getBatteryStats()) {
459            service.stats.stopRunningLocked();
460        }
461        service.startRequested = false;
462        if (service.tracker != null) {
463            service.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
464                    SystemClock.uptimeMillis());
465        }
466        service.callStart = false;
467        bringDownServiceIfNeededLocked(service, false, false);
468    }
469
470    int stopServiceLocked(IApplicationThread caller, Intent service,
471            String resolvedType, int userId) {
472        if (DEBUG_SERVICE) Slog.v(TAG, "stopService: " + service
473                + " type=" + resolvedType);
474
475        final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
476        if (caller != null && callerApp == null) {
477            throw new SecurityException(
478                    "Unable to find app for caller " + caller
479                    + " (pid=" + Binder.getCallingPid()
480                    + ") when stopping service " + service);
481        }
482
483        // If this service is active, make sure it is stopped.
484        ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
485                Binder.getCallingPid(), Binder.getCallingUid(), userId, false, false);
486        if (r != null) {
487            if (r.record != null) {
488                final long origId = Binder.clearCallingIdentity();
489                try {
490                    stopServiceLocked(r.record);
491                } finally {
492                    Binder.restoreCallingIdentity(origId);
493                }
494                return 1;
495            }
496            return -1;
497        }
498
499        return 0;
500    }
501
502    IBinder peekServiceLocked(Intent service, String resolvedType) {
503        ServiceLookupResult r = retrieveServiceLocked(service, resolvedType,
504                Binder.getCallingPid(), Binder.getCallingUid(),
505                UserHandle.getCallingUserId(), false, false);
506
507        IBinder ret = null;
508        if (r != null) {
509            // r.record is null if findServiceLocked() failed the caller permission check
510            if (r.record == null) {
511                throw new SecurityException(
512                        "Permission Denial: Accessing service " + r.record.name
513                        + " from pid=" + Binder.getCallingPid()
514                        + ", uid=" + Binder.getCallingUid()
515                        + " requires " + r.permission);
516            }
517            IntentBindRecord ib = r.record.bindings.get(r.record.intent);
518            if (ib != null) {
519                ret = ib.binder;
520            }
521        }
522
523        return ret;
524    }
525
526    boolean stopServiceTokenLocked(ComponentName className, IBinder token,
527            int startId) {
528        if (DEBUG_SERVICE) Slog.v(TAG, "stopServiceToken: " + className
529                + " " + token + " startId=" + startId);
530        ServiceRecord r = findServiceLocked(className, token, UserHandle.getCallingUserId());
531        if (r != null) {
532            if (startId >= 0) {
533                // Asked to only stop if done with all work.  Note that
534                // to avoid leaks, we will take this as dropping all
535                // start items up to and including this one.
536                ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
537                if (si != null) {
538                    while (r.deliveredStarts.size() > 0) {
539                        ServiceRecord.StartItem cur = r.deliveredStarts.remove(0);
540                        cur.removeUriPermissionsLocked();
541                        if (cur == si) {
542                            break;
543                        }
544                    }
545                }
546
547                if (r.getLastStartId() != startId) {
548                    return false;
549                }
550
551                if (r.deliveredStarts.size() > 0) {
552                    Slog.w(TAG, "stopServiceToken startId " + startId
553                            + " is last, but have " + r.deliveredStarts.size()
554                            + " remaining args");
555                }
556            }
557
558            synchronized (r.stats.getBatteryStats()) {
559                r.stats.stopRunningLocked();
560            }
561            r.startRequested = false;
562            if (r.tracker != null) {
563                r.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
564                        SystemClock.uptimeMillis());
565            }
566            r.callStart = false;
567            final long origId = Binder.clearCallingIdentity();
568            bringDownServiceIfNeededLocked(r, false, false);
569            Binder.restoreCallingIdentity(origId);
570            return true;
571        }
572        return false;
573    }
574
575    public void setServiceForegroundLocked(ComponentName className, IBinder token,
576            int id, Notification notification, boolean removeNotification) {
577        final int userId = UserHandle.getCallingUserId();
578        final long origId = Binder.clearCallingIdentity();
579        try {
580            ServiceRecord r = findServiceLocked(className, token, userId);
581            if (r != null) {
582                if (id != 0) {
583                    if (notification == null) {
584                        throw new IllegalArgumentException("null notification");
585                    }
586                    if (r.foregroundId != id) {
587                        r.cancelNotification();
588                        r.foregroundId = id;
589                    }
590                    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;
591                    r.foregroundNoti = notification;
592                    r.isForeground = true;
593                    r.postNotification();
594                    if (r.app != null) {
595                        updateServiceForegroundLocked(r.app, true);
596                    }
597                    getServiceMap(r.userId).ensureNotStartingBackground(r);
598                } else {
599                    if (r.isForeground) {
600                        r.isForeground = false;
601                        if (r.app != null) {
602                            mAm.updateLruProcessLocked(r.app, false, null);
603                            updateServiceForegroundLocked(r.app, true);
604                        }
605                    }
606                    if (removeNotification) {
607                        r.cancelNotification();
608                        r.foregroundId = 0;
609                        r.foregroundNoti = null;
610                    } else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
611                        r.stripForegroundServiceFlagFromNotification();
612                    }
613                }
614            }
615        } finally {
616            Binder.restoreCallingIdentity(origId);
617        }
618    }
619
620    private void updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj) {
621        boolean anyForeground = false;
622        for (int i=proc.services.size()-1; i>=0; i--) {
623            ServiceRecord sr = proc.services.valueAt(i);
624            if (sr.isForeground) {
625                anyForeground = true;
626                break;
627            }
628        }
629        mAm.updateProcessForegroundLocked(proc, anyForeground, oomAdj);
630    }
631
632    public void updateServiceConnectionActivitiesLocked(ProcessRecord clientProc) {
633        ArraySet<ProcessRecord> updatedProcesses = null;
634        for (int i=0; i<clientProc.connections.size(); i++) {
635            final ConnectionRecord conn = clientProc.connections.valueAt(i);
636            final ProcessRecord proc = conn.binding.service.app;
637            if (proc == null || proc == clientProc) {
638                continue;
639            } else if (updatedProcesses == null) {
640                updatedProcesses = new ArraySet<>();
641            } else if (updatedProcesses.contains(proc)) {
642                continue;
643            }
644            updatedProcesses.add(proc);
645            updateServiceClientActivitiesLocked(proc, null, false);
646        }
647    }
648
649    private boolean updateServiceClientActivitiesLocked(ProcessRecord proc,
650            ConnectionRecord modCr, boolean updateLru) {
651        if (modCr != null && modCr.binding.client != null) {
652            if (modCr.binding.client.activities.size() <= 0) {
653                // This connection is from a client without activities, so adding
654                // and removing is not interesting.
655                return false;
656            }
657        }
658
659        boolean anyClientActivities = false;
660        for (int i=proc.services.size()-1; i>=0 && !anyClientActivities; i--) {
661            ServiceRecord sr = proc.services.valueAt(i);
662            for (int conni=sr.connections.size()-1; conni>=0 && !anyClientActivities; conni--) {
663                ArrayList<ConnectionRecord> clist = sr.connections.valueAt(conni);
664                for (int cri=clist.size()-1; cri>=0; cri--) {
665                    ConnectionRecord cr = clist.get(cri);
666                    if (cr.binding.client == null || cr.binding.client == proc) {
667                        // Binding to ourself is not interesting.
668                        continue;
669                    }
670                    if (cr.binding.client.activities.size() > 0) {
671                        anyClientActivities = true;
672                        break;
673                    }
674                }
675            }
676        }
677        if (anyClientActivities != proc.hasClientActivities) {
678            proc.hasClientActivities = anyClientActivities;
679            if (updateLru) {
680                mAm.updateLruProcessLocked(proc, anyClientActivities, null);
681            }
682            return true;
683        }
684        return false;
685    }
686
687    int bindServiceLocked(IApplicationThread caller, IBinder token,
688            Intent service, String resolvedType,
689            IServiceConnection connection, int flags, int userId) {
690        if (DEBUG_SERVICE) Slog.v(TAG, "bindService: " + service
691                + " type=" + resolvedType + " conn=" + connection.asBinder()
692                + " flags=0x" + Integer.toHexString(flags));
693        final ProcessRecord callerApp = mAm.getRecordForAppLocked(caller);
694        if (callerApp == null) {
695            throw new SecurityException(
696                    "Unable to find app for caller " + caller
697                    + " (pid=" + Binder.getCallingPid()
698                    + ") when binding service " + service);
699        }
700
701        ActivityRecord activity = null;
702        if (token != null) {
703            activity = ActivityRecord.isInStackLocked(token);
704            if (activity == null) {
705                Slog.w(TAG, "Binding with unknown activity: " + token);
706                return 0;
707            }
708        }
709
710        int clientLabel = 0;
711        PendingIntent clientIntent = null;
712
713        if (callerApp.info.uid == Process.SYSTEM_UID) {
714            // Hacky kind of thing -- allow system stuff to tell us
715            // what they are, so we can report this elsewhere for
716            // others to know why certain services are running.
717            try {
718                clientIntent = service.getParcelableExtra(Intent.EXTRA_CLIENT_INTENT);
719            } catch (RuntimeException e) {
720            }
721            if (clientIntent != null) {
722                clientLabel = service.getIntExtra(Intent.EXTRA_CLIENT_LABEL, 0);
723                if (clientLabel != 0) {
724                    // There are no useful extras in the intent, trash them.
725                    // System code calling with this stuff just needs to know
726                    // this will happen.
727                    service = service.cloneFilter();
728                }
729            }
730        }
731
732        if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
733            mAm.enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
734                    "BIND_TREAT_LIKE_ACTIVITY");
735        }
736
737        final boolean callerFg = callerApp.setSchedGroup != Process.THREAD_GROUP_BG_NONINTERACTIVE;
738
739        ServiceLookupResult res =
740            retrieveServiceLocked(service, resolvedType,
741                    Binder.getCallingPid(), Binder.getCallingUid(), userId, true, callerFg);
742        if (res == null) {
743            return 0;
744        }
745        if (res.record == null) {
746            return -1;
747        }
748        ServiceRecord s = res.record;
749
750        final long origId = Binder.clearCallingIdentity();
751
752        try {
753            if (unscheduleServiceRestartLocked(s, callerApp.info.uid, false)) {
754                if (DEBUG_SERVICE) Slog.v(TAG, "BIND SERVICE WHILE RESTART PENDING: "
755                        + s);
756            }
757
758            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
759                s.lastActivity = SystemClock.uptimeMillis();
760                if (!s.hasAutoCreateConnections()) {
761                    // This is the first binding, let the tracker know.
762                    ProcessStats.ServiceState stracker = s.getTracker();
763                    if (stracker != null) {
764                        stracker.setBound(true, mAm.mProcessStats.getMemFactorLocked(),
765                                s.lastActivity);
766                    }
767                }
768            }
769
770            mAm.startAssociationLocked(callerApp.uid, callerApp.processName,
771                    s.appInfo.uid, s.name, s.processName);
772
773            AppBindRecord b = s.retrieveAppBindingLocked(service, callerApp);
774            ConnectionRecord c = new ConnectionRecord(b, activity,
775                    connection, flags, clientLabel, clientIntent);
776
777            IBinder binder = connection.asBinder();
778            ArrayList<ConnectionRecord> clist = s.connections.get(binder);
779            if (clist == null) {
780                clist = new ArrayList<ConnectionRecord>();
781                s.connections.put(binder, clist);
782            }
783            clist.add(c);
784            b.connections.add(c);
785            if (activity != null) {
786                if (activity.connections == null) {
787                    activity.connections = new HashSet<ConnectionRecord>();
788                }
789                activity.connections.add(c);
790            }
791            b.client.connections.add(c);
792            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
793                b.client.hasAboveClient = true;
794            }
795            if (s.app != null) {
796                updateServiceClientActivitiesLocked(s.app, c, true);
797            }
798            clist = mServiceConnections.get(binder);
799            if (clist == null) {
800                clist = new ArrayList<ConnectionRecord>();
801                mServiceConnections.put(binder, clist);
802            }
803            clist.add(c);
804
805            if ((flags&Context.BIND_AUTO_CREATE) != 0) {
806                s.lastActivity = SystemClock.uptimeMillis();
807                if (bringUpServiceLocked(s, service.getFlags(), callerFg, false) != null) {
808                    return 0;
809                }
810            }
811
812            if (s.app != null) {
813                if ((flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
814                    s.app.treatLikeActivity = true;
815                }
816                // This could have made the service more important.
817                mAm.updateLruProcessLocked(s.app, s.app.hasClientActivities
818                        || s.app.treatLikeActivity, b.client);
819                mAm.updateOomAdjLocked(s.app);
820            }
821
822            if (DEBUG_SERVICE) Slog.v(TAG, "Bind " + s + " with " + b
823                    + ": received=" + b.intent.received
824                    + " apps=" + b.intent.apps.size()
825                    + " doRebind=" + b.intent.doRebind);
826
827            if (s.app != null && b.intent.received) {
828                // Service is already running, so we can immediately
829                // publish the connection.
830                try {
831                    c.conn.connected(s.name, b.intent.binder);
832                } catch (Exception e) {
833                    Slog.w(TAG, "Failure sending service " + s.shortName
834                            + " to connection " + c.conn.asBinder()
835                            + " (in " + c.binding.client.processName + ")", e);
836                }
837
838                // If this is the first app connected back to this binding,
839                // and the service had previously asked to be told when
840                // rebound, then do so.
841                if (b.intent.apps.size() == 1 && b.intent.doRebind) {
842                    requestServiceBindingLocked(s, b.intent, callerFg, true);
843                }
844            } else if (!b.intent.requested) {
845                requestServiceBindingLocked(s, b.intent, callerFg, false);
846            }
847
848            getServiceMap(s.userId).ensureNotStartingBackground(s);
849
850        } finally {
851            Binder.restoreCallingIdentity(origId);
852        }
853
854        return 1;
855    }
856
857    void publishServiceLocked(ServiceRecord r, Intent intent, IBinder service) {
858        final long origId = Binder.clearCallingIdentity();
859        try {
860            if (DEBUG_SERVICE) Slog.v(TAG, "PUBLISHING " + r
861                    + " " + intent + ": " + service);
862            if (r != null) {
863                Intent.FilterComparison filter
864                        = new Intent.FilterComparison(intent);
865                IntentBindRecord b = r.bindings.get(filter);
866                if (b != null && !b.received) {
867                    b.binder = service;
868                    b.requested = true;
869                    b.received = true;
870                    for (int conni=r.connections.size()-1; conni>=0; conni--) {
871                        ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
872                        for (int i=0; i<clist.size(); i++) {
873                            ConnectionRecord c = clist.get(i);
874                            if (!filter.equals(c.binding.intent.intent)) {
875                                if (DEBUG_SERVICE) Slog.v(
876                                        TAG, "Not publishing to: " + c);
877                                if (DEBUG_SERVICE) Slog.v(
878                                        TAG, "Bound intent: " + c.binding.intent.intent);
879                                if (DEBUG_SERVICE) Slog.v(
880                                        TAG, "Published intent: " + intent);
881                                continue;
882                            }
883                            if (DEBUG_SERVICE) Slog.v(TAG, "Publishing to: " + c);
884                            try {
885                                c.conn.connected(r.name, service);
886                            } catch (Exception e) {
887                                Slog.w(TAG, "Failure sending service " + r.name +
888                                      " to connection " + c.conn.asBinder() +
889                                      " (in " + c.binding.client.processName + ")", e);
890                            }
891                        }
892                    }
893                }
894
895                serviceDoneExecutingLocked(r, mDestroyingServices.contains(r), false);
896            }
897        } finally {
898            Binder.restoreCallingIdentity(origId);
899        }
900    }
901
902    boolean unbindServiceLocked(IServiceConnection connection) {
903        IBinder binder = connection.asBinder();
904        if (DEBUG_SERVICE) Slog.v(TAG, "unbindService: conn=" + binder);
905        ArrayList<ConnectionRecord> clist = mServiceConnections.get(binder);
906        if (clist == null) {
907            Slog.w(TAG, "Unbind failed: could not find connection for "
908                  + connection.asBinder());
909            return false;
910        }
911
912        final long origId = Binder.clearCallingIdentity();
913        try {
914            while (clist.size() > 0) {
915                ConnectionRecord r = clist.get(0);
916                removeConnectionLocked(r, null, null);
917                if (clist.size() > 0 && clist.get(0) == r) {
918                    // In case it didn't get removed above, do it now.
919                    Slog.wtf(TAG, "Connection " + r + " not removed for binder " + binder);
920                    clist.remove(0);
921                }
922
923                if (r.binding.service.app != null) {
924                    // This could have made the service less important.
925                    if ((r.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
926                        r.binding.service.app.treatLikeActivity = true;
927                        mAm.updateLruProcessLocked(r.binding.service.app,
928                                r.binding.service.app.hasClientActivities
929                                || r.binding.service.app.treatLikeActivity, null);
930                    }
931                    mAm.updateOomAdjLocked(r.binding.service.app);
932                }
933            }
934        } finally {
935            Binder.restoreCallingIdentity(origId);
936        }
937
938        return true;
939    }
940
941    void unbindFinishedLocked(ServiceRecord r, Intent intent, boolean doRebind) {
942        final long origId = Binder.clearCallingIdentity();
943        try {
944            if (r != null) {
945                Intent.FilterComparison filter
946                        = new Intent.FilterComparison(intent);
947                IntentBindRecord b = r.bindings.get(filter);
948                if (DEBUG_SERVICE) Slog.v(TAG, "unbindFinished in " + r
949                        + " at " + b + ": apps="
950                        + (b != null ? b.apps.size() : 0));
951
952                boolean inDestroying = mDestroyingServices.contains(r);
953                if (b != null) {
954                    if (b.apps.size() > 0 && !inDestroying) {
955                        // Applications have already bound since the last
956                        // unbind, so just rebind right here.
957                        boolean inFg = false;
958                        for (int i=b.apps.size()-1; i>=0; i--) {
959                            ProcessRecord client = b.apps.valueAt(i).client;
960                            if (client != null && client.setSchedGroup
961                                    != Process.THREAD_GROUP_BG_NONINTERACTIVE) {
962                                inFg = true;
963                                break;
964                            }
965                        }
966                        requestServiceBindingLocked(r, b, inFg, true);
967                    } else {
968                        // Note to tell the service the next time there is
969                        // a new client.
970                        b.doRebind = true;
971                    }
972                }
973
974                serviceDoneExecutingLocked(r, inDestroying, false);
975            }
976        } finally {
977            Binder.restoreCallingIdentity(origId);
978        }
979    }
980
981    private final ServiceRecord findServiceLocked(ComponentName name,
982            IBinder token, int userId) {
983        ServiceRecord r = getServiceByName(name, userId);
984        return r == token ? r : null;
985    }
986
987    private final class ServiceLookupResult {
988        final ServiceRecord record;
989        final String permission;
990
991        ServiceLookupResult(ServiceRecord _record, String _permission) {
992            record = _record;
993            permission = _permission;
994        }
995    }
996
997    private class ServiceRestarter implements Runnable {
998        private ServiceRecord mService;
999
1000        void setService(ServiceRecord service) {
1001            mService = service;
1002        }
1003
1004        public void run() {
1005            synchronized(mAm) {
1006                performServiceRestartLocked(mService);
1007            }
1008        }
1009    }
1010
1011    private ServiceLookupResult retrieveServiceLocked(Intent service,
1012            String resolvedType, int callingPid, int callingUid, int userId,
1013            boolean createIfNeeded, boolean callingFromFg) {
1014        ServiceRecord r = null;
1015        if (DEBUG_SERVICE) Slog.v(TAG, "retrieveServiceLocked: " + service
1016                + " type=" + resolvedType + " callingUid=" + callingUid);
1017
1018        userId = mAm.handleIncomingUser(callingPid, callingUid, userId,
1019                false, ActivityManagerService.ALLOW_NON_FULL_IN_PROFILE, "service", null);
1020
1021        ServiceMap smap = getServiceMap(userId);
1022        final ComponentName comp = service.getComponent();
1023        if (comp != null) {
1024            r = smap.mServicesByName.get(comp);
1025        }
1026        if (r == null) {
1027            Intent.FilterComparison filter = new Intent.FilterComparison(service);
1028            r = smap.mServicesByIntent.get(filter);
1029        }
1030        if (r == null) {
1031            try {
1032                ResolveInfo rInfo =
1033                    AppGlobals.getPackageManager().resolveService(
1034                                service, resolvedType,
1035                                ActivityManagerService.STOCK_PM_FLAGS, userId);
1036                ServiceInfo sInfo =
1037                    rInfo != null ? rInfo.serviceInfo : null;
1038                if (sInfo == null) {
1039                    Slog.w(TAG, "Unable to start service " + service + " U=" + userId +
1040                          ": not found");
1041                    return null;
1042                }
1043                ComponentName name = new ComponentName(
1044                        sInfo.applicationInfo.packageName, sInfo.name);
1045                if (userId > 0) {
1046                    if (mAm.isSingleton(sInfo.processName, sInfo.applicationInfo,
1047                            sInfo.name, sInfo.flags)
1048                            && mAm.isValidSingletonCall(callingUid, sInfo.applicationInfo.uid)) {
1049                        userId = 0;
1050                        smap = getServiceMap(0);
1051                    }
1052                    sInfo = new ServiceInfo(sInfo);
1053                    sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
1054                }
1055                r = smap.mServicesByName.get(name);
1056                if (r == null && createIfNeeded) {
1057                    Intent.FilterComparison filter
1058                            = new Intent.FilterComparison(service.cloneFilter());
1059                    ServiceRestarter res = new ServiceRestarter();
1060                    BatteryStatsImpl.Uid.Pkg.Serv ss = null;
1061                    BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics();
1062                    synchronized (stats) {
1063                        ss = stats.getServiceStatsLocked(
1064                                sInfo.applicationInfo.uid, sInfo.packageName,
1065                                sInfo.name);
1066                    }
1067                    r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res);
1068                    res.setService(r);
1069                    smap.mServicesByName.put(name, r);
1070                    smap.mServicesByIntent.put(filter, r);
1071
1072                    // Make sure this component isn't in the pending list.
1073                    for (int i=mPendingServices.size()-1; i>=0; i--) {
1074                        ServiceRecord pr = mPendingServices.get(i);
1075                        if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
1076                                && pr.name.equals(name)) {
1077                            mPendingServices.remove(i);
1078                        }
1079                    }
1080                }
1081            } catch (RemoteException ex) {
1082                // pm is in same process, this will never happen.
1083            }
1084        }
1085        if (r != null) {
1086            if (mAm.checkComponentPermission(r.permission,
1087                    callingPid, callingUid, r.appInfo.uid, r.exported)
1088                    != PackageManager.PERMISSION_GRANTED) {
1089                if (!r.exported) {
1090                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
1091                            + " from pid=" + callingPid
1092                            + ", uid=" + callingUid
1093                            + " that is not exported from uid " + r.appInfo.uid);
1094                    return new ServiceLookupResult(null, "not exported from uid "
1095                            + r.appInfo.uid);
1096                }
1097                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
1098                        + " from pid=" + callingPid
1099                        + ", uid=" + callingUid
1100                        + " requires " + r.permission);
1101                return new ServiceLookupResult(null, r.permission);
1102            }
1103            if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
1104                    resolvedType, r.appInfo)) {
1105                return null;
1106            }
1107            return new ServiceLookupResult(r, null);
1108        }
1109        return null;
1110    }
1111
1112    private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
1113        if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING "
1114                + why + " of " + r + " in app " + r.app);
1115        else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, ">>> EXECUTING "
1116                + why + " of " + r.shortName);
1117        long now = SystemClock.uptimeMillis();
1118        if (r.executeNesting == 0) {
1119            r.executeFg = fg;
1120            ProcessStats.ServiceState stracker = r.getTracker();
1121            if (stracker != null) {
1122                stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
1123            }
1124            if (r.app != null) {
1125                r.app.executingServices.add(r);
1126                r.app.execServicesFg |= fg;
1127                if (r.app.executingServices.size() == 1) {
1128                    scheduleServiceTimeoutLocked(r.app);
1129                }
1130            }
1131        } else if (r.app != null && fg && !r.app.execServicesFg) {
1132            r.app.execServicesFg = true;
1133            scheduleServiceTimeoutLocked(r.app);
1134        }
1135        r.executeFg |= fg;
1136        r.executeNesting++;
1137        r.executingStart = now;
1138    }
1139
1140    private final boolean requestServiceBindingLocked(ServiceRecord r,
1141            IntentBindRecord i, boolean execInFg, boolean rebind) {
1142        if (r.app == null || r.app.thread == null) {
1143            // If service is not currently running, can't yet bind.
1144            return false;
1145        }
1146        if ((!i.requested || rebind) && i.apps.size() > 0) {
1147            try {
1148                bumpServiceExecutingLocked(r, execInFg, "bind");
1149                r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
1150                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
1151                        r.app.repProcState);
1152                if (!rebind) {
1153                    i.requested = true;
1154                }
1155                i.hasBound = true;
1156                i.doRebind = false;
1157            } catch (RemoteException e) {
1158                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
1159                return false;
1160            }
1161        }
1162        return true;
1163    }
1164
1165    private final boolean scheduleServiceRestartLocked(ServiceRecord r,
1166            boolean allowCancel) {
1167        boolean canceled = false;
1168
1169        ServiceMap smap = getServiceMap(r.userId);
1170        if (smap.mServicesByName.get(r.name) != r) {
1171            ServiceRecord cur = smap.mServicesByName.get(r.name);
1172            Slog.wtf(TAG, "Attempting to schedule restart of " + r
1173                    + " when found in map: " + cur);
1174            return false;
1175        }
1176
1177        final long now = SystemClock.uptimeMillis();
1178
1179        if ((r.serviceInfo.applicationInfo.flags
1180                &ApplicationInfo.FLAG_PERSISTENT) == 0) {
1181            long minDuration = SERVICE_RESTART_DURATION;
1182            long resetTime = SERVICE_RESET_RUN_DURATION;
1183
1184            // Any delivered but not yet finished starts should be put back
1185            // on the pending list.
1186            final int N = r.deliveredStarts.size();
1187            if (N > 0) {
1188                for (int i=N-1; i>=0; i--) {
1189                    ServiceRecord.StartItem si = r.deliveredStarts.get(i);
1190                    si.removeUriPermissionsLocked();
1191                    if (si.intent == null) {
1192                        // We'll generate this again if needed.
1193                    } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
1194                            && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
1195                        r.pendingStarts.add(0, si);
1196                        long dur = SystemClock.uptimeMillis() - si.deliveredTime;
1197                        dur *= 2;
1198                        if (minDuration < dur) minDuration = dur;
1199                        if (resetTime < dur) resetTime = dur;
1200                    } else {
1201                        Slog.w(TAG, "Canceling start item " + si.intent + " in service "
1202                                + r.name);
1203                        canceled = true;
1204                    }
1205                }
1206                r.deliveredStarts.clear();
1207            }
1208
1209            r.totalRestartCount++;
1210            if (r.restartDelay == 0) {
1211                r.restartCount++;
1212                r.restartDelay = minDuration;
1213            } else {
1214                // If it has been a "reasonably long time" since the service
1215                // was started, then reset our restart duration back to
1216                // the beginning, so we don't infinitely increase the duration
1217                // on a service that just occasionally gets killed (which is
1218                // a normal case, due to process being killed to reclaim memory).
1219                if (now > (r.restartTime+resetTime)) {
1220                    r.restartCount = 1;
1221                    r.restartDelay = minDuration;
1222                } else {
1223                    r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
1224                    if (r.restartDelay < minDuration) {
1225                        r.restartDelay = minDuration;
1226                    }
1227                }
1228            }
1229
1230            r.nextRestartTime = now + r.restartDelay;
1231
1232            // Make sure that we don't end up restarting a bunch of services
1233            // all at the same time.
1234            boolean repeat;
1235            do {
1236                repeat = false;
1237                for (int i=mRestartingServices.size()-1; i>=0; i--) {
1238                    ServiceRecord r2 = mRestartingServices.get(i);
1239                    if (r2 != r && r.nextRestartTime
1240                            >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
1241                            && r.nextRestartTime
1242                            < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
1243                        r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
1244                        r.restartDelay = r.nextRestartTime - now;
1245                        repeat = true;
1246                        break;
1247                    }
1248                }
1249            } while (repeat);
1250
1251        } else {
1252            // Persistent processes are immediately restarted, so there is no
1253            // reason to hold of on restarting their services.
1254            r.totalRestartCount++;
1255            r.restartCount = 0;
1256            r.restartDelay = 0;
1257            r.nextRestartTime = now;
1258        }
1259
1260        if (!mRestartingServices.contains(r)) {
1261            r.createdFromFg = false;
1262            mRestartingServices.add(r);
1263            r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);
1264        }
1265
1266        r.cancelNotification();
1267
1268        mAm.mHandler.removeCallbacks(r.restarter);
1269        mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime);
1270        r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
1271        Slog.w(TAG, "Scheduling restart of crashed service "
1272                + r.shortName + " in " + r.restartDelay + "ms");
1273        EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
1274                r.userId, r.shortName, r.restartDelay);
1275
1276        return canceled;
1277    }
1278
1279    final void performServiceRestartLocked(ServiceRecord r) {
1280        if (!mRestartingServices.contains(r)) {
1281            return;
1282        }
1283        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true);
1284    }
1285
1286    private final boolean unscheduleServiceRestartLocked(ServiceRecord r, int callingUid,
1287            boolean force) {
1288        if (!force && r.restartDelay == 0) {
1289            return false;
1290        }
1291        // Remove from the restarting list; if the service is currently on the
1292        // restarting list, or the call is coming from another app, then this
1293        // service has become of much more interest so we reset the restart interval.
1294        boolean removed = mRestartingServices.remove(r);
1295        if (removed || callingUid != r.appInfo.uid) {
1296            r.resetRestartCounter();
1297        }
1298        if (removed) {
1299            clearRestartingIfNeededLocked(r);
1300        }
1301        mAm.mHandler.removeCallbacks(r.restarter);
1302        return true;
1303    }
1304
1305    private void clearRestartingIfNeededLocked(ServiceRecord r) {
1306        if (r.restartTracker != null) {
1307            // If this is the last restarting record with this tracker, then clear
1308            // the tracker's restarting state.
1309            boolean stillTracking = false;
1310            for (int i=mRestartingServices.size()-1; i>=0; i--) {
1311                if (mRestartingServices.get(i).restartTracker == r.restartTracker) {
1312                    stillTracking = true;
1313                    break;
1314                }
1315            }
1316            if (!stillTracking) {
1317                r.restartTracker.setRestarting(false, mAm.mProcessStats.getMemFactorLocked(),
1318                        SystemClock.uptimeMillis());
1319                r.restartTracker = null;
1320            }
1321        }
1322    }
1323
1324    private final String bringUpServiceLocked(ServiceRecord r,
1325            int intentFlags, boolean execInFg, boolean whileRestarting) {
1326        //Slog.i(TAG, "Bring up service:");
1327        //r.dump("  ");
1328
1329        if (r.app != null && r.app.thread != null) {
1330            sendServiceArgsLocked(r, execInFg, false);
1331            return null;
1332        }
1333
1334        if (!whileRestarting && r.restartDelay > 0) {
1335            // If waiting for a restart, then do nothing.
1336            return null;
1337        }
1338
1339        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
1340
1341        // We are now bringing the service up, so no longer in the
1342        // restarting state.
1343        if (mRestartingServices.remove(r)) {
1344            clearRestartingIfNeededLocked(r);
1345        }
1346
1347        // Make sure this service is no longer considered delayed, we are starting it now.
1348        if (r.delayed) {
1349            if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "REM FR DELAY LIST (bring up): " + r);
1350            getServiceMap(r.userId).mDelayedStartList.remove(r);
1351            r.delayed = false;
1352        }
1353
1354        // Make sure that the user who owns this service is started.  If not,
1355        // we don't want to allow it to run.
1356        if (mAm.mStartedUsers.get(r.userId) == null) {
1357            String msg = "Unable to launch app "
1358                    + r.appInfo.packageName + "/"
1359                    + r.appInfo.uid + " for service "
1360                    + r.intent.getIntent() + ": user " + r.userId + " is stopped";
1361            Slog.w(TAG, msg);
1362            bringDownServiceLocked(r);
1363            return msg;
1364        }
1365
1366        // Service is now being launched, its package can't be stopped.
1367        try {
1368            AppGlobals.getPackageManager().setPackageStoppedState(
1369                    r.packageName, false, r.userId);
1370        } catch (RemoteException e) {
1371        } catch (IllegalArgumentException e) {
1372            Slog.w(TAG, "Failed trying to unstop package "
1373                    + r.packageName + ": " + e);
1374        }
1375
1376        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
1377        final String procName = r.processName;
1378        ProcessRecord app;
1379
1380        if (!isolated) {
1381            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
1382            if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
1383                        + " app=" + app);
1384            if (app != null && app.thread != null) {
1385                try {
1386                    app.addPackage(r.appInfo.packageName, r.appInfo.versionCode, mAm.mProcessStats);
1387                    realStartServiceLocked(r, app, execInFg);
1388                    return null;
1389                } catch (RemoteException e) {
1390                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
1391                }
1392
1393                // If a dead object exception was thrown -- fall through to
1394                // restart the application.
1395            }
1396        } else {
1397            // If this service runs in an isolated process, then each time
1398            // we call startProcessLocked() we will get a new isolated
1399            // process, starting another process if we are currently waiting
1400            // for a previous process to come up.  To deal with this, we store
1401            // in the service any current isolated process it is running in or
1402            // waiting to have come up.
1403            app = r.isolatedProc;
1404        }
1405
1406        // Not running -- get it started, and enqueue this service record
1407        // to be executed when the app comes up.
1408        if (app == null) {
1409            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
1410                    "service", r.name, false, isolated, false)) == null) {
1411                String msg = "Unable to launch app "
1412                        + r.appInfo.packageName + "/"
1413                        + r.appInfo.uid + " for service "
1414                        + r.intent.getIntent() + ": process is bad";
1415                Slog.w(TAG, msg);
1416                bringDownServiceLocked(r);
1417                return msg;
1418            }
1419            if (isolated) {
1420                r.isolatedProc = app;
1421            }
1422        }
1423
1424        if (!mPendingServices.contains(r)) {
1425            mPendingServices.add(r);
1426        }
1427
1428        if (r.delayedStop) {
1429            // Oh and hey we've already been asked to stop!
1430            r.delayedStop = false;
1431            if (r.startRequested) {
1432                if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Applying delayed stop (in bring up): " + r);
1433                stopServiceLocked(r);
1434            }
1435        }
1436
1437        return null;
1438    }
1439
1440    private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg) {
1441        for (int i=r.bindings.size()-1; i>=0; i--) {
1442            IntentBindRecord ibr = r.bindings.valueAt(i);
1443            if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
1444                break;
1445            }
1446        }
1447    }
1448
1449    private final void realStartServiceLocked(ServiceRecord r,
1450            ProcessRecord app, boolean execInFg) throws RemoteException {
1451        if (app.thread == null) {
1452            throw new RemoteException();
1453        }
1454        if (DEBUG_MU)
1455            Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
1456                    + ", ProcessRecord.uid = " + app.uid);
1457        r.app = app;
1458        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
1459
1460        app.services.add(r);
1461        bumpServiceExecutingLocked(r, execInFg, "create");
1462        mAm.updateLruProcessLocked(app, false, null);
1463        mAm.updateOomAdjLocked();
1464
1465        boolean created = false;
1466        try {
1467            if (LOG_SERVICE_START_STOP) {
1468                String nameTerm;
1469                int lastPeriod = r.shortName.lastIndexOf('.');
1470                nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
1471                EventLogTags.writeAmCreateService(
1472                        r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
1473            }
1474            synchronized (r.stats.getBatteryStats()) {
1475                r.stats.startLaunchedLocked();
1476            }
1477            mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
1478            app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
1479            app.thread.scheduleCreateService(r, r.serviceInfo,
1480                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
1481                    app.repProcState);
1482            r.postNotification();
1483            created = true;
1484        } catch (DeadObjectException e) {
1485            Slog.w(TAG, "Application dead when creating service " + r);
1486            mAm.appDiedLocked(app);
1487        } finally {
1488            if (!created) {
1489                app.services.remove(r);
1490                r.app = null;
1491                scheduleServiceRestartLocked(r, false);
1492                return;
1493            }
1494        }
1495
1496        requestServiceBindingsLocked(r, execInFg);
1497
1498        updateServiceClientActivitiesLocked(app, null, true);
1499
1500        // If the service is in the started state, and there are no
1501        // pending arguments, then fake up one so its onStartCommand() will
1502        // be called.
1503        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
1504            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
1505                    null, null));
1506        }
1507
1508        sendServiceArgsLocked(r, execInFg, true);
1509
1510        if (r.delayed) {
1511            if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "REM FR DELAY LIST (new proc): " + r);
1512            getServiceMap(r.userId).mDelayedStartList.remove(r);
1513            r.delayed = false;
1514        }
1515
1516        if (r.delayedStop) {
1517            // Oh and hey we've already been asked to stop!
1518            r.delayedStop = false;
1519            if (r.startRequested) {
1520                if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Applying delayed stop (from start): " + r);
1521                stopServiceLocked(r);
1522            }
1523        }
1524    }
1525
1526    private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
1527            boolean oomAdjusted) {
1528        final int N = r.pendingStarts.size();
1529        if (N == 0) {
1530            return;
1531        }
1532
1533        while (r.pendingStarts.size() > 0) {
1534            try {
1535                ServiceRecord.StartItem si = r.pendingStarts.remove(0);
1536                if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
1537                        + r + " " + r.intent + " args=" + si.intent);
1538                if (si.intent == null && N > 1) {
1539                    // If somehow we got a dummy null intent in the middle,
1540                    // then skip it.  DO NOT skip a null intent when it is
1541                    // the only one in the list -- this is to support the
1542                    // onStartCommand(null) case.
1543                    continue;
1544                }
1545                si.deliveredTime = SystemClock.uptimeMillis();
1546                r.deliveredStarts.add(si);
1547                si.deliveryCount++;
1548                if (si.neededGrants != null) {
1549                    mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
1550                            si.getUriPermissionsLocked());
1551                }
1552                bumpServiceExecutingLocked(r, execInFg, "start");
1553                if (!oomAdjusted) {
1554                    oomAdjusted = true;
1555                    mAm.updateOomAdjLocked(r.app);
1556                }
1557                int flags = 0;
1558                if (si.deliveryCount > 1) {
1559                    flags |= Service.START_FLAG_RETRY;
1560                }
1561                if (si.doneExecutingCount > 0) {
1562                    flags |= Service.START_FLAG_REDELIVERY;
1563                }
1564                r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
1565            } catch (RemoteException e) {
1566                // Remote process gone...  we'll let the normal cleanup take
1567                // care of this.
1568                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
1569                break;
1570            } catch (Exception e) {
1571                Slog.w(TAG, "Unexpected exception", e);
1572                break;
1573            }
1574        }
1575    }
1576
1577    private final boolean isServiceNeeded(ServiceRecord r, boolean knowConn, boolean hasConn) {
1578        // Are we still explicitly being asked to run?
1579        if (r.startRequested) {
1580            return true;
1581        }
1582
1583        // Is someone still bound to us keepign us running?
1584        if (!knowConn) {
1585            hasConn = r.hasAutoCreateConnections();
1586        }
1587        if (hasConn) {
1588            return true;
1589        }
1590
1591        return false;
1592    }
1593
1594    private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
1595            boolean hasConn) {
1596        //Slog.i(TAG, "Bring down service:");
1597        //r.dump("  ");
1598
1599        if (isServiceNeeded(r, knowConn, hasConn)) {
1600            return;
1601        }
1602
1603        // Are we in the process of launching?
1604        if (mPendingServices.contains(r)) {
1605            return;
1606        }
1607
1608        bringDownServiceLocked(r);
1609    }
1610
1611    private final void bringDownServiceLocked(ServiceRecord r) {
1612        //Slog.i(TAG, "Bring down service:");
1613        //r.dump("  ");
1614
1615        // Report to all of the connections that the service is no longer
1616        // available.
1617        for (int conni=r.connections.size()-1; conni>=0; conni--) {
1618            ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
1619            for (int i=0; i<c.size(); i++) {
1620                ConnectionRecord cr = c.get(i);
1621                // There is still a connection to the service that is
1622                // being brought down.  Mark it as dead.
1623                cr.serviceDead = true;
1624                try {
1625                    cr.conn.connected(r.name, null);
1626                } catch (Exception e) {
1627                    Slog.w(TAG, "Failure disconnecting service " + r.name +
1628                          " to connection " + c.get(i).conn.asBinder() +
1629                          " (in " + c.get(i).binding.client.processName + ")", e);
1630                }
1631            }
1632        }
1633
1634        // Tell the service that it has been unbound.
1635        if (r.app != null && r.app.thread != null) {
1636            for (int i=r.bindings.size()-1; i>=0; i--) {
1637                IntentBindRecord ibr = r.bindings.valueAt(i);
1638                if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
1639                        + ": hasBound=" + ibr.hasBound);
1640                if (ibr.hasBound) {
1641                    try {
1642                        bumpServiceExecutingLocked(r, false, "bring down unbind");
1643                        mAm.updateOomAdjLocked(r.app);
1644                        ibr.hasBound = false;
1645                        r.app.thread.scheduleUnbindService(r,
1646                                ibr.intent.getIntent());
1647                    } catch (Exception e) {
1648                        Slog.w(TAG, "Exception when unbinding service "
1649                                + r.shortName, e);
1650                        serviceProcessGoneLocked(r);
1651                    }
1652                }
1653            }
1654        }
1655
1656        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
1657        r.destroyTime = SystemClock.uptimeMillis();
1658        if (LOG_SERVICE_START_STOP) {
1659            EventLogTags.writeAmDestroyService(
1660                    r.userId, System.identityHashCode(r), (r.app != null) ? r.app.pid : -1);
1661        }
1662
1663        final ServiceMap smap = getServiceMap(r.userId);
1664        smap.mServicesByName.remove(r.name);
1665        smap.mServicesByIntent.remove(r.intent);
1666        r.totalRestartCount = 0;
1667        unscheduleServiceRestartLocked(r, 0, true);
1668
1669        // Also make sure it is not on the pending list.
1670        for (int i=mPendingServices.size()-1; i>=0; i--) {
1671            if (mPendingServices.get(i) == r) {
1672                mPendingServices.remove(i);
1673                if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
1674            }
1675        }
1676
1677        r.cancelNotification();
1678        r.isForeground = false;
1679        r.foregroundId = 0;
1680        r.foregroundNoti = null;
1681
1682        // Clear start entries.
1683        r.clearDeliveredStartsLocked();
1684        r.pendingStarts.clear();
1685
1686        if (r.app != null) {
1687            synchronized (r.stats.getBatteryStats()) {
1688                r.stats.stopLaunchedLocked();
1689            }
1690            r.app.services.remove(r);
1691            if (r.app.thread != null) {
1692                updateServiceForegroundLocked(r.app, false);
1693                try {
1694                    bumpServiceExecutingLocked(r, false, "destroy");
1695                    mDestroyingServices.add(r);
1696                    r.destroying = true;
1697                    mAm.updateOomAdjLocked(r.app);
1698                    r.app.thread.scheduleStopService(r);
1699                } catch (Exception e) {
1700                    Slog.w(TAG, "Exception when destroying service "
1701                            + r.shortName, e);
1702                    serviceProcessGoneLocked(r);
1703                }
1704            } else {
1705                if (DEBUG_SERVICE) Slog.v(
1706                    TAG, "Removed service that has no process: " + r);
1707            }
1708        } else {
1709            if (DEBUG_SERVICE) Slog.v(
1710                TAG, "Removed service that is not running: " + r);
1711        }
1712
1713        if (r.bindings.size() > 0) {
1714            r.bindings.clear();
1715        }
1716
1717        if (r.restarter instanceof ServiceRestarter) {
1718           ((ServiceRestarter)r.restarter).setService(null);
1719        }
1720
1721        int memFactor = mAm.mProcessStats.getMemFactorLocked();
1722        long now = SystemClock.uptimeMillis();
1723        if (r.tracker != null) {
1724            r.tracker.setStarted(false, memFactor, now);
1725            r.tracker.setBound(false, memFactor, now);
1726            if (r.executeNesting == 0) {
1727                r.tracker.clearCurrentOwner(r, false);
1728                r.tracker = null;
1729            }
1730        }
1731
1732        smap.ensureNotStartingBackground(r);
1733    }
1734
1735    void removeConnectionLocked(
1736        ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
1737        IBinder binder = c.conn.asBinder();
1738        AppBindRecord b = c.binding;
1739        ServiceRecord s = b.service;
1740        ArrayList<ConnectionRecord> clist = s.connections.get(binder);
1741        if (clist != null) {
1742            clist.remove(c);
1743            if (clist.size() == 0) {
1744                s.connections.remove(binder);
1745            }
1746        }
1747        b.connections.remove(c);
1748        if (c.activity != null && c.activity != skipAct) {
1749            if (c.activity.connections != null) {
1750                c.activity.connections.remove(c);
1751            }
1752        }
1753        if (b.client != skipApp) {
1754            b.client.connections.remove(c);
1755            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
1756                b.client.updateHasAboveClientLocked();
1757            }
1758            if (s.app != null) {
1759                updateServiceClientActivitiesLocked(s.app, c, true);
1760            }
1761        }
1762        clist = mServiceConnections.get(binder);
1763        if (clist != null) {
1764            clist.remove(c);
1765            if (clist.size() == 0) {
1766                mServiceConnections.remove(binder);
1767            }
1768        }
1769
1770        mAm.stopAssociationLocked(b.client.uid, b.client.processName, s.appInfo.uid, s.name);
1771
1772        if (b.connections.size() == 0) {
1773            b.intent.apps.remove(b.client);
1774        }
1775
1776        if (!c.serviceDead) {
1777            if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
1778                    + ": shouldUnbind=" + b.intent.hasBound);
1779            if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
1780                    && b.intent.hasBound) {
1781                try {
1782                    bumpServiceExecutingLocked(s, false, "unbind");
1783                    if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0
1784                            && s.app.setProcState <= ActivityManager.PROCESS_STATE_RECEIVER) {
1785                        // If this service's process is not already in the cached list,
1786                        // then update it in the LRU list here because this may be causing
1787                        // it to go down there and we want it to start out near the top.
1788                        mAm.updateLruProcessLocked(s.app, false, null);
1789                    }
1790                    mAm.updateOomAdjLocked(s.app);
1791                    b.intent.hasBound = false;
1792                    // Assume the client doesn't want to know about a rebind;
1793                    // we will deal with that later if it asks for one.
1794                    b.intent.doRebind = false;
1795                    s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
1796                } catch (Exception e) {
1797                    Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
1798                    serviceProcessGoneLocked(s);
1799                }
1800            }
1801
1802            if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
1803                boolean hasAutoCreate = s.hasAutoCreateConnections();
1804                if (!hasAutoCreate) {
1805                    if (s.tracker != null) {
1806                        s.tracker.setBound(false, mAm.mProcessStats.getMemFactorLocked(),
1807                                SystemClock.uptimeMillis());
1808                    }
1809                }
1810                bringDownServiceIfNeededLocked(s, true, hasAutoCreate);
1811            }
1812        }
1813    }
1814
1815    void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
1816        boolean inDestroying = mDestroyingServices.contains(r);
1817        if (r != null) {
1818            if (type == ActivityThread.SERVICE_DONE_EXECUTING_START) {
1819                // This is a call from a service start...  take care of
1820                // book-keeping.
1821                r.callStart = true;
1822                switch (res) {
1823                    case Service.START_STICKY_COMPATIBILITY:
1824                    case Service.START_STICKY: {
1825                        // We are done with the associated start arguments.
1826                        r.findDeliveredStart(startId, true);
1827                        // Don't stop if killed.
1828                        r.stopIfKilled = false;
1829                        break;
1830                    }
1831                    case Service.START_NOT_STICKY: {
1832                        // We are done with the associated start arguments.
1833                        r.findDeliveredStart(startId, true);
1834                        if (r.getLastStartId() == startId) {
1835                            // There is no more work, and this service
1836                            // doesn't want to hang around if killed.
1837                            r.stopIfKilled = true;
1838                        }
1839                        break;
1840                    }
1841                    case Service.START_REDELIVER_INTENT: {
1842                        // We'll keep this item until they explicitly
1843                        // call stop for it, but keep track of the fact
1844                        // that it was delivered.
1845                        ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
1846                        if (si != null) {
1847                            si.deliveryCount = 0;
1848                            si.doneExecutingCount++;
1849                            // Don't stop if killed.
1850                            r.stopIfKilled = true;
1851                        }
1852                        break;
1853                    }
1854                    case Service.START_TASK_REMOVED_COMPLETE: {
1855                        // Special processing for onTaskRemoved().  Don't
1856                        // impact normal onStartCommand() processing.
1857                        r.findDeliveredStart(startId, true);
1858                        break;
1859                    }
1860                    default:
1861                        throw new IllegalArgumentException(
1862                                "Unknown service start result: " + res);
1863                }
1864                if (res == Service.START_STICKY_COMPATIBILITY) {
1865                    r.callStart = false;
1866                }
1867            } else if (type == ActivityThread.SERVICE_DONE_EXECUTING_STOP) {
1868                // This is the final call from destroying the service...  we should
1869                // actually be getting rid of the service at this point.  Do some
1870                // validation of its state, and ensure it will be fully removed.
1871                if (!inDestroying) {
1872                    // Not sure what else to do with this...  if it is not actually in the
1873                    // destroying list, we don't need to make sure to remove it from it.
1874                    Slog.wtfStack(TAG, "Service done with onDestroy, but not inDestroying: "
1875                            + r);
1876                } else if (r.executeNesting != 1) {
1877                    Slog.wtfStack(TAG, "Service done with onDestroy, but executeNesting="
1878                            + r.executeNesting + ": " + r);
1879                    r.executeNesting = 1;
1880                }
1881            }
1882            final long origId = Binder.clearCallingIdentity();
1883            serviceDoneExecutingLocked(r, inDestroying, inDestroying);
1884            Binder.restoreCallingIdentity(origId);
1885        } else {
1886            Slog.w(TAG, "Done executing unknown service from pid "
1887                    + Binder.getCallingPid());
1888        }
1889    }
1890
1891    private void serviceProcessGoneLocked(ServiceRecord r) {
1892        if (r.tracker != null) {
1893            int memFactor = mAm.mProcessStats.getMemFactorLocked();
1894            long now = SystemClock.uptimeMillis();
1895            r.tracker.setExecuting(false, memFactor, now);
1896            r.tracker.setBound(false, memFactor, now);
1897            r.tracker.setStarted(false, memFactor, now);
1898        }
1899        serviceDoneExecutingLocked(r, true, true);
1900    }
1901
1902    private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
1903            boolean finishing) {
1904        if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
1905                + ": nesting=" + r.executeNesting
1906                + ", inDestroying=" + inDestroying + ", app=" + r.app);
1907        else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
1908        r.executeNesting--;
1909        if (r.executeNesting <= 0) {
1910            if (r.app != null) {
1911                if (DEBUG_SERVICE) Slog.v(TAG,
1912                        "Nesting at 0 of " + r.shortName);
1913                r.app.execServicesFg = false;
1914                r.app.executingServices.remove(r);
1915                if (r.app.executingServices.size() == 0) {
1916                    if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
1917                            "No more executingServices of " + r.shortName);
1918                    mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
1919                } else if (r.executeFg) {
1920                    // Need to re-evaluate whether the app still needs to be in the foreground.
1921                    for (int i=r.app.executingServices.size()-1; i>=0; i--) {
1922                        if (r.app.executingServices.valueAt(i).executeFg) {
1923                            r.app.execServicesFg = true;
1924                            break;
1925                        }
1926                    }
1927                }
1928                if (inDestroying) {
1929                    if (DEBUG_SERVICE) Slog.v(TAG,
1930                            "doneExecuting remove destroying " + r);
1931                    mDestroyingServices.remove(r);
1932                    r.bindings.clear();
1933                }
1934                mAm.updateOomAdjLocked(r.app);
1935            }
1936            r.executeFg = false;
1937            if (r.tracker != null) {
1938                r.tracker.setExecuting(false, mAm.mProcessStats.getMemFactorLocked(),
1939                        SystemClock.uptimeMillis());
1940                if (finishing) {
1941                    r.tracker.clearCurrentOwner(r, false);
1942                    r.tracker = null;
1943                }
1944            }
1945            if (finishing) {
1946                if (r.app != null && !r.app.persistent) {
1947                    r.app.services.remove(r);
1948                }
1949                r.app = null;
1950            }
1951        }
1952    }
1953
1954    boolean attachApplicationLocked(ProcessRecord proc, String processName)
1955            throws RemoteException {
1956        boolean didSomething = false;
1957        // Collect any services that are waiting for this process to come up.
1958        if (mPendingServices.size() > 0) {
1959            ServiceRecord sr = null;
1960            try {
1961                for (int i=0; i<mPendingServices.size(); i++) {
1962                    sr = mPendingServices.get(i);
1963                    if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
1964                            || !processName.equals(sr.processName))) {
1965                        continue;
1966                    }
1967
1968                    mPendingServices.remove(i);
1969                    i--;
1970                    proc.addPackage(sr.appInfo.packageName, sr.appInfo.versionCode,
1971                            mAm.mProcessStats);
1972                    realStartServiceLocked(sr, proc, sr.createdFromFg);
1973                    didSomething = true;
1974                }
1975            } catch (RemoteException e) {
1976                Slog.w(TAG, "Exception in new application when starting service "
1977                        + sr.shortName, e);
1978                throw e;
1979            }
1980        }
1981        // Also, if there are any services that are waiting to restart and
1982        // would run in this process, now is a good time to start them.  It would
1983        // be weird to bring up the process but arbitrarily not let the services
1984        // run at this point just because their restart time hasn't come up.
1985        if (mRestartingServices.size() > 0) {
1986            ServiceRecord sr = null;
1987            for (int i=0; i<mRestartingServices.size(); i++) {
1988                sr = mRestartingServices.get(i);
1989                if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
1990                        || !processName.equals(sr.processName))) {
1991                    continue;
1992                }
1993                mAm.mHandler.removeCallbacks(sr.restarter);
1994                mAm.mHandler.post(sr.restarter);
1995            }
1996        }
1997        return didSomething;
1998    }
1999
2000    void processStartTimedOutLocked(ProcessRecord proc) {
2001        for (int i=0; i<mPendingServices.size(); i++) {
2002            ServiceRecord sr = mPendingServices.get(i);
2003            if ((proc.uid == sr.appInfo.uid
2004                    && proc.processName.equals(sr.processName))
2005                    || sr.isolatedProc == proc) {
2006                Slog.w(TAG, "Forcing bringing down service: " + sr);
2007                sr.isolatedProc = null;
2008                mPendingServices.remove(i);
2009                i--;
2010                bringDownServiceLocked(sr);
2011            }
2012        }
2013    }
2014
2015    private boolean collectForceStopServicesLocked(String name, int userId,
2016            boolean evenPersistent, boolean doit,
2017            ArrayMap<ComponentName, ServiceRecord> services,
2018            ArrayList<ServiceRecord> result) {
2019        boolean didSomething = false;
2020        for (int i=0; i<services.size(); i++) {
2021            ServiceRecord service = services.valueAt(i);
2022            if ((name == null || service.packageName.equals(name))
2023                    && (service.app == null || evenPersistent || !service.app.persistent)) {
2024                if (!doit) {
2025                    return true;
2026                }
2027                didSomething = true;
2028                Slog.i(TAG, "  Force stopping service " + service);
2029                if (service.app != null) {
2030                    service.app.removed = true;
2031                    if (!service.app.persistent) {
2032                        service.app.services.remove(service);
2033                    }
2034                }
2035                service.app = null;
2036                service.isolatedProc = null;
2037                result.add(service);
2038            }
2039        }
2040        return didSomething;
2041    }
2042
2043    boolean forceStopLocked(String name, int userId, boolean evenPersistent, boolean doit) {
2044        boolean didSomething = false;
2045        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
2046        if (userId == UserHandle.USER_ALL) {
2047            for (int i=0; i<mServiceMap.size(); i++) {
2048                didSomething |= collectForceStopServicesLocked(name, userId, evenPersistent,
2049                        doit, mServiceMap.valueAt(i).mServicesByName, services);
2050                if (!doit && didSomething) {
2051                    return true;
2052                }
2053            }
2054        } else {
2055            ServiceMap smap = mServiceMap.get(userId);
2056            if (smap != null) {
2057                ArrayMap<ComponentName, ServiceRecord> items = smap.mServicesByName;
2058                didSomething = collectForceStopServicesLocked(name, userId, evenPersistent,
2059                        doit, items, services);
2060            }
2061        }
2062
2063        int N = services.size();
2064        for (int i=0; i<N; i++) {
2065            bringDownServiceLocked(services.get(i));
2066        }
2067        return didSomething;
2068    }
2069
2070    void cleanUpRemovedTaskLocked(TaskRecord tr, ComponentName component, Intent baseIntent) {
2071        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
2072        ArrayMap<ComponentName, ServiceRecord> alls = getServices(tr.userId);
2073        for (int i=0; i<alls.size(); i++) {
2074            ServiceRecord sr = alls.valueAt(i);
2075            if (sr.packageName.equals(component.getPackageName())) {
2076                services.add(sr);
2077            }
2078        }
2079
2080        // Take care of any running services associated with the app.
2081        for (int i=0; i<services.size(); i++) {
2082            ServiceRecord sr = services.get(i);
2083            if (sr.startRequested) {
2084                if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
2085                    Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
2086                    stopServiceLocked(sr);
2087                } else {
2088                    sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
2089                            sr.makeNextStartId(), baseIntent, null));
2090                    if (sr.app != null && sr.app.thread != null) {
2091                        // We always run in the foreground, since this is called as
2092                        // part of the "remove task" UI operation.
2093                        sendServiceArgsLocked(sr, true, false);
2094                    }
2095                }
2096            }
2097        }
2098    }
2099
2100    final void killServicesLocked(ProcessRecord app, boolean allowRestart) {
2101        // Report disconnected services.
2102        if (false) {
2103            // XXX we are letting the client link to the service for
2104            // death notifications.
2105            if (app.services.size() > 0) {
2106                Iterator<ServiceRecord> it = app.services.iterator();
2107                while (it.hasNext()) {
2108                    ServiceRecord r = it.next();
2109                    for (int conni=r.connections.size()-1; conni>=0; conni--) {
2110                        ArrayList<ConnectionRecord> cl = r.connections.valueAt(conni);
2111                        for (int i=0; i<cl.size(); i++) {
2112                            ConnectionRecord c = cl.get(i);
2113                            if (c.binding.client != app) {
2114                                try {
2115                                    //c.conn.connected(r.className, null);
2116                                } catch (Exception e) {
2117                                    // todo: this should be asynchronous!
2118                                    Slog.w(TAG, "Exception thrown disconnected servce "
2119                                          + r.shortName
2120                                          + " from app " + app.processName, e);
2121                                }
2122                            }
2123                        }
2124                    }
2125                }
2126            }
2127        }
2128
2129        // First clear app state from services.
2130        for (int i=app.services.size()-1; i>=0; i--) {
2131            ServiceRecord sr = app.services.valueAt(i);
2132            synchronized (sr.stats.getBatteryStats()) {
2133                sr.stats.stopLaunchedLocked();
2134            }
2135            if (sr.app != app && sr.app != null && !sr.app.persistent) {
2136                sr.app.services.remove(sr);
2137            }
2138            sr.app = null;
2139            sr.isolatedProc = null;
2140            sr.executeNesting = 0;
2141            sr.forceClearTracker();
2142            if (mDestroyingServices.remove(sr)) {
2143                if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove destroying " + sr);
2144            }
2145
2146            final int numClients = sr.bindings.size();
2147            for (int bindingi=numClients-1; bindingi>=0; bindingi--) {
2148                IntentBindRecord b = sr.bindings.valueAt(bindingi);
2149                if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
2150                        + ": shouldUnbind=" + b.hasBound);
2151                b.binder = null;
2152                b.requested = b.received = b.hasBound = false;
2153                // If this binding is coming from a cached process and is asking to keep
2154                // the service created, then we'll kill the cached process as well -- we
2155                // don't want to be thrashing around restarting processes that are only
2156                // there to be cached.
2157                for (int appi=b.apps.size()-1; appi>=0; appi--) {
2158                    final ProcessRecord proc = b.apps.keyAt(appi);
2159                    // If the process is already gone, skip it.
2160                    if (proc.killedByAm || proc.thread == null) {
2161                        continue;
2162                    }
2163                    // Only do this for processes that have an auto-create binding;
2164                    // otherwise the binding can be left, because it won't cause the
2165                    // service to restart.
2166                    final AppBindRecord abind = b.apps.valueAt(appi);
2167                    boolean hasCreate = false;
2168                    for (int conni=abind.connections.size()-1; conni>=0; conni--) {
2169                        ConnectionRecord conn = abind.connections.valueAt(conni);
2170                        if ((conn.flags&(Context.BIND_AUTO_CREATE|Context.BIND_ALLOW_OOM_MANAGEMENT
2171                                |Context.BIND_WAIVE_PRIORITY)) == Context.BIND_AUTO_CREATE) {
2172                            hasCreate = true;
2173                            break;
2174                        }
2175                    }
2176                    if (!hasCreate) {
2177                        continue;
2178                    }
2179                    // XXX turned off for now until we have more time to get a better policy.
2180                    if (false && proc != null && !proc.persistent && proc.thread != null
2181                            && proc.pid != 0 && proc.pid != ActivityManagerService.MY_PID
2182                            && proc.setProcState >= ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
2183                        proc.kill("bound to service " + sr.name.flattenToShortString()
2184                                + " in dying proc " + (app != null ? app.processName : "??"), true);
2185                    }
2186                }
2187            }
2188        }
2189
2190        // Clean up any connections this application has to other services.
2191        for (int i=app.connections.size()-1; i>=0; i--) {
2192            ConnectionRecord r = app.connections.valueAt(i);
2193            removeConnectionLocked(r, app, null);
2194        }
2195        updateServiceConnectionActivitiesLocked(app);
2196        app.connections.clear();
2197
2198        ServiceMap smap = getServiceMap(app.userId);
2199
2200        // Now do remaining service cleanup.
2201        for (int i=app.services.size()-1; i>=0; i--) {
2202            ServiceRecord sr = app.services.valueAt(i);
2203
2204            // Unless the process is persistent, this process record is going away,
2205            // so make sure the service is cleaned out of it.
2206            if (!app.persistent) {
2207                app.services.removeAt(i);
2208            }
2209
2210            // Sanity check: if the service listed for the app is not one
2211            // we actually are maintaining, just let it drop.
2212            final ServiceRecord curRec = smap.mServicesByName.get(sr.name);
2213            if (curRec != sr) {
2214                if (curRec != null) {
2215                    Slog.wtf(TAG, "Service " + sr + " in process " + app
2216                            + " not same as in map: " + curRec);
2217                }
2218                continue;
2219            }
2220
2221            // Any services running in the application may need to be placed
2222            // back in the pending list.
2223            if (allowRestart && sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
2224                    &ApplicationInfo.FLAG_PERSISTENT) == 0) {
2225                Slog.w(TAG, "Service crashed " + sr.crashCount
2226                        + " times, stopping: " + sr);
2227                EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
2228                        sr.userId, sr.crashCount, sr.shortName, app.pid);
2229                bringDownServiceLocked(sr);
2230            } else if (!allowRestart) {
2231                bringDownServiceLocked(sr);
2232            } else {
2233                boolean canceled = scheduleServiceRestartLocked(sr, true);
2234
2235                // Should the service remain running?  Note that in the
2236                // extreme case of so many attempts to deliver a command
2237                // that it failed we also will stop it here.
2238                if (sr.startRequested && (sr.stopIfKilled || canceled)) {
2239                    if (sr.pendingStarts.size() == 0) {
2240                        sr.startRequested = false;
2241                        if (sr.tracker != null) {
2242                            sr.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
2243                                    SystemClock.uptimeMillis());
2244                        }
2245                        if (!sr.hasAutoCreateConnections()) {
2246                            // Whoops, no reason to restart!
2247                            bringDownServiceLocked(sr);
2248                        }
2249                    }
2250                }
2251            }
2252        }
2253
2254        if (!allowRestart) {
2255            app.services.clear();
2256
2257            // Make sure there are no more restarting services for this process.
2258            for (int i=mRestartingServices.size()-1; i>=0; i--) {
2259                ServiceRecord r = mRestartingServices.get(i);
2260                if (r.processName.equals(app.processName) &&
2261                        r.serviceInfo.applicationInfo.uid == app.info.uid) {
2262                    mRestartingServices.remove(i);
2263                    clearRestartingIfNeededLocked(r);
2264                }
2265            }
2266            for (int i=mPendingServices.size()-1; i>=0; i--) {
2267                ServiceRecord r = mPendingServices.get(i);
2268                if (r.processName.equals(app.processName) &&
2269                        r.serviceInfo.applicationInfo.uid == app.info.uid) {
2270                    mPendingServices.remove(i);
2271                }
2272            }
2273        }
2274
2275        // Make sure we have no more records on the stopping list.
2276        int i = mDestroyingServices.size();
2277        while (i > 0) {
2278            i--;
2279            ServiceRecord sr = mDestroyingServices.get(i);
2280            if (sr.app == app) {
2281                sr.forceClearTracker();
2282                mDestroyingServices.remove(i);
2283                if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove destroying " + sr);
2284            }
2285        }
2286
2287        app.executingServices.clear();
2288    }
2289
2290    ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
2291        ActivityManager.RunningServiceInfo info =
2292            new ActivityManager.RunningServiceInfo();
2293        info.service = r.name;
2294        if (r.app != null) {
2295            info.pid = r.app.pid;
2296        }
2297        info.uid = r.appInfo.uid;
2298        info.process = r.processName;
2299        info.foreground = r.isForeground;
2300        info.activeSince = r.createTime;
2301        info.started = r.startRequested;
2302        info.clientCount = r.connections.size();
2303        info.crashCount = r.crashCount;
2304        info.lastActivityTime = r.lastActivity;
2305        if (r.isForeground) {
2306            info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
2307        }
2308        if (r.startRequested) {
2309            info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
2310        }
2311        if (r.app != null && r.app.pid == ActivityManagerService.MY_PID) {
2312            info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
2313        }
2314        if (r.app != null && r.app.persistent) {
2315            info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
2316        }
2317
2318        for (int conni=r.connections.size()-1; conni>=0; conni--) {
2319            ArrayList<ConnectionRecord> connl = r.connections.valueAt(conni);
2320            for (int i=0; i<connl.size(); i++) {
2321                ConnectionRecord conn = connl.get(i);
2322                if (conn.clientLabel != 0) {
2323                    info.clientPackage = conn.binding.client.info.packageName;
2324                    info.clientLabel = conn.clientLabel;
2325                    return info;
2326                }
2327            }
2328        }
2329        return info;
2330    }
2331
2332    List<ActivityManager.RunningServiceInfo> getRunningServiceInfoLocked(int maxNum,
2333            int flags) {
2334        ArrayList<ActivityManager.RunningServiceInfo> res
2335                = new ArrayList<ActivityManager.RunningServiceInfo>();
2336
2337        final int uid = Binder.getCallingUid();
2338        final long ident = Binder.clearCallingIdentity();
2339        try {
2340            if (ActivityManager.checkUidPermission(
2341                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2342                    uid) == PackageManager.PERMISSION_GRANTED) {
2343                int[] users = mAm.getUsersLocked();
2344                for (int ui=0; ui<users.length && res.size() < maxNum; ui++) {
2345                    ArrayMap<ComponentName, ServiceRecord> alls = getServices(users[ui]);
2346                    for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
2347                        ServiceRecord sr = alls.valueAt(i);
2348                        res.add(makeRunningServiceInfoLocked(sr));
2349                    }
2350                }
2351
2352                for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
2353                    ServiceRecord r = mRestartingServices.get(i);
2354                    ActivityManager.RunningServiceInfo info =
2355                            makeRunningServiceInfoLocked(r);
2356                    info.restarting = r.nextRestartTime;
2357                    res.add(info);
2358                }
2359            } else {
2360                int userId = UserHandle.getUserId(uid);
2361                ArrayMap<ComponentName, ServiceRecord> alls = getServices(userId);
2362                for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
2363                    ServiceRecord sr = alls.valueAt(i);
2364                    res.add(makeRunningServiceInfoLocked(sr));
2365                }
2366
2367                for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
2368                    ServiceRecord r = mRestartingServices.get(i);
2369                    if (r.userId == userId) {
2370                        ActivityManager.RunningServiceInfo info =
2371                                makeRunningServiceInfoLocked(r);
2372                        info.restarting = r.nextRestartTime;
2373                        res.add(info);
2374                    }
2375                }
2376            }
2377        } finally {
2378            Binder.restoreCallingIdentity(ident);
2379        }
2380
2381        return res;
2382    }
2383
2384    public PendingIntent getRunningServiceControlPanelLocked(ComponentName name) {
2385        int userId = UserHandle.getUserId(Binder.getCallingUid());
2386        ServiceRecord r = getServiceByName(name, userId);
2387        if (r != null) {
2388            for (int conni=r.connections.size()-1; conni>=0; conni--) {
2389                ArrayList<ConnectionRecord> conn = r.connections.valueAt(conni);
2390                for (int i=0; i<conn.size(); i++) {
2391                    if (conn.get(i).clientIntent != null) {
2392                        return conn.get(i).clientIntent;
2393                    }
2394                }
2395            }
2396        }
2397        return null;
2398    }
2399
2400    void serviceTimeout(ProcessRecord proc) {
2401        String anrMessage = null;
2402
2403        synchronized(mAm) {
2404            if (proc.executingServices.size() == 0 || proc.thread == null) {
2405                return;
2406            }
2407            final long now = SystemClock.uptimeMillis();
2408            final long maxTime =  now -
2409                    (proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
2410            ServiceRecord timeout = null;
2411            long nextTime = 0;
2412            for (int i=proc.executingServices.size()-1; i>=0; i--) {
2413                ServiceRecord sr = proc.executingServices.valueAt(i);
2414                if (sr.executingStart < maxTime) {
2415                    timeout = sr;
2416                    break;
2417                }
2418                if (sr.executingStart > nextTime) {
2419                    nextTime = sr.executingStart;
2420                }
2421            }
2422            if (timeout != null && mAm.mLruProcesses.contains(proc)) {
2423                Slog.w(TAG, "Timeout executing service: " + timeout);
2424                StringWriter sw = new StringWriter();
2425                PrintWriter pw = new FastPrintWriter(sw, false, 1024);
2426                pw.println(timeout);
2427                timeout.dump(pw, "    ");
2428                pw.close();
2429                mLastAnrDump = sw.toString();
2430                mAm.mHandler.removeCallbacks(mLastAnrDumpClearer);
2431                mAm.mHandler.postDelayed(mLastAnrDumpClearer, LAST_ANR_LIFETIME_DURATION_MSECS);
2432                anrMessage = "executing service " + timeout.shortName;
2433            } else {
2434                Message msg = mAm.mHandler.obtainMessage(
2435                        ActivityManagerService.SERVICE_TIMEOUT_MSG);
2436                msg.obj = proc;
2437                mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg
2438                        ? (nextTime+SERVICE_TIMEOUT) : (nextTime + SERVICE_BACKGROUND_TIMEOUT));
2439            }
2440        }
2441
2442        if (anrMessage != null) {
2443            mAm.appNotResponding(proc, null, null, false, anrMessage);
2444        }
2445    }
2446
2447    void scheduleServiceTimeoutLocked(ProcessRecord proc) {
2448        if (proc.executingServices.size() == 0 || proc.thread == null) {
2449            return;
2450        }
2451        long now = SystemClock.uptimeMillis();
2452        Message msg = mAm.mHandler.obtainMessage(
2453                ActivityManagerService.SERVICE_TIMEOUT_MSG);
2454        msg.obj = proc;
2455        mAm.mHandler.sendMessageAtTime(msg,
2456                proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
2457    }
2458
2459    /**
2460     * Prints a list of ServiceRecords (dumpsys activity services)
2461     */
2462    void dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
2463            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
2464        boolean needSep = false;
2465        boolean printedAnything = false;
2466
2467        ItemMatcher matcher = new ItemMatcher();
2468        matcher.build(args, opti);
2469
2470        pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
2471        try {
2472            if (mLastAnrDump != null) {
2473                pw.println("  Last ANR service:");
2474                pw.print(mLastAnrDump);
2475                pw.println();
2476            }
2477            int[] users = mAm.getUsersLocked();
2478            for (int user : users) {
2479                ServiceMap smap = getServiceMap(user);
2480                boolean printed = false;
2481                if (smap.mServicesByName.size() > 0) {
2482                    long nowReal = SystemClock.elapsedRealtime();
2483                    needSep = false;
2484                    for (int si=0; si<smap.mServicesByName.size(); si++) {
2485                        ServiceRecord r = smap.mServicesByName.valueAt(si);
2486                        if (!matcher.match(r, r.name)) {
2487                            continue;
2488                        }
2489                        if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2490                            continue;
2491                        }
2492                        if (!printed) {
2493                            if (printedAnything) {
2494                                pw.println();
2495                            }
2496                            pw.println("  User " + user + " active services:");
2497                            printed = true;
2498                        }
2499                        printedAnything = true;
2500                        if (needSep) {
2501                            pw.println();
2502                        }
2503                        pw.print("  * ");
2504                        pw.println(r);
2505                        if (dumpAll) {
2506                            r.dump(pw, "    ");
2507                            needSep = true;
2508                        } else {
2509                            pw.print("    app=");
2510                            pw.println(r.app);
2511                            pw.print("    created=");
2512                            TimeUtils.formatDuration(r.createTime, nowReal, pw);
2513                            pw.print(" started=");
2514                            pw.print(r.startRequested);
2515                            pw.print(" connections=");
2516                            pw.println(r.connections.size());
2517                            if (r.connections.size() > 0) {
2518                                pw.println("    Connections:");
2519                                for (int conni=0; conni<r.connections.size(); conni++) {
2520                                    ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
2521                                    for (int i = 0; i < clist.size(); i++) {
2522                                        ConnectionRecord conn = clist.get(i);
2523                                        pw.print("      ");
2524                                        pw.print(conn.binding.intent.intent.getIntent()
2525                                                .toShortString(false, false, false, false));
2526                                        pw.print(" -> ");
2527                                        ProcessRecord proc = conn.binding.client;
2528                                        pw.println(proc != null ? proc.toShortString() : "null");
2529                                    }
2530                                }
2531                            }
2532                        }
2533                        if (dumpClient && r.app != null && r.app.thread != null) {
2534                            pw.println("    Client:");
2535                            pw.flush();
2536                            try {
2537                                TransferPipe tp = new TransferPipe();
2538                                try {
2539                                    r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(),
2540                                            r, args);
2541                                    tp.setBufferPrefix("      ");
2542                                    // Short timeout, since blocking here can
2543                                    // deadlock with the application.
2544                                    tp.go(fd, 2000);
2545                                } finally {
2546                                    tp.kill();
2547                                }
2548                            } catch (IOException e) {
2549                                pw.println("      Failure while dumping the service: " + e);
2550                            } catch (RemoteException e) {
2551                                pw.println("      Got a RemoteException while dumping the service");
2552                            }
2553                            needSep = true;
2554                        }
2555                    }
2556                    needSep |= printed;
2557                }
2558                printed = false;
2559                for (int si=0, SN=smap.mDelayedStartList.size(); si<SN; si++) {
2560                    ServiceRecord r = smap.mDelayedStartList.get(si);
2561                    if (!matcher.match(r, r.name)) {
2562                        continue;
2563                    }
2564                    if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2565                        continue;
2566                    }
2567                    if (!printed) {
2568                        if (printedAnything) {
2569                            pw.println();
2570                        }
2571                        pw.println("  User " + user + " delayed start services:");
2572                        printed = true;
2573                    }
2574                    printedAnything = true;
2575                    pw.print("  * Delayed start "); pw.println(r);
2576                }
2577                printed = false;
2578                for (int si=0, SN=smap.mStartingBackground.size(); si<SN; si++) {
2579                    ServiceRecord r = smap.mStartingBackground.get(si);
2580                    if (!matcher.match(r, r.name)) {
2581                        continue;
2582                    }
2583                    if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2584                        continue;
2585                    }
2586                    if (!printed) {
2587                        if (printedAnything) {
2588                            pw.println();
2589                        }
2590                        pw.println("  User " + user + " starting in background:");
2591                        printed = true;
2592                    }
2593                    printedAnything = true;
2594                    pw.print("  * Starting bg "); pw.println(r);
2595                }
2596            }
2597        } catch (Exception e) {
2598            Slog.w(TAG, "Exception in dumpServicesLocked", e);
2599        }
2600
2601        if (mPendingServices.size() > 0) {
2602            boolean printed = false;
2603            for (int i=0; i<mPendingServices.size(); i++) {
2604                ServiceRecord r = mPendingServices.get(i);
2605                if (!matcher.match(r, r.name)) {
2606                    continue;
2607                }
2608                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2609                    continue;
2610                }
2611                printedAnything = true;
2612                if (!printed) {
2613                    if (needSep) pw.println();
2614                    needSep = true;
2615                    pw.println("  Pending services:");
2616                    printed = true;
2617                }
2618                pw.print("  * Pending "); pw.println(r);
2619                r.dump(pw, "    ");
2620            }
2621            needSep = true;
2622        }
2623
2624        if (mRestartingServices.size() > 0) {
2625            boolean printed = false;
2626            for (int i=0; i<mRestartingServices.size(); i++) {
2627                ServiceRecord r = mRestartingServices.get(i);
2628                if (!matcher.match(r, r.name)) {
2629                    continue;
2630                }
2631                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2632                    continue;
2633                }
2634                printedAnything = true;
2635                if (!printed) {
2636                    if (needSep) pw.println();
2637                    needSep = true;
2638                    pw.println("  Restarting services:");
2639                    printed = true;
2640                }
2641                pw.print("  * Restarting "); pw.println(r);
2642                r.dump(pw, "    ");
2643            }
2644            needSep = true;
2645        }
2646
2647        if (mDestroyingServices.size() > 0) {
2648            boolean printed = false;
2649            for (int i=0; i< mDestroyingServices.size(); i++) {
2650                ServiceRecord r = mDestroyingServices.get(i);
2651                if (!matcher.match(r, r.name)) {
2652                    continue;
2653                }
2654                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2655                    continue;
2656                }
2657                printedAnything = true;
2658                if (!printed) {
2659                    if (needSep) pw.println();
2660                    needSep = true;
2661                    pw.println("  Destroying services:");
2662                    printed = true;
2663                }
2664                pw.print("  * Destroy "); pw.println(r);
2665                r.dump(pw, "    ");
2666            }
2667            needSep = true;
2668        }
2669
2670        if (dumpAll) {
2671            boolean printed = false;
2672            for (int ic=0; ic<mServiceConnections.size(); ic++) {
2673                ArrayList<ConnectionRecord> r = mServiceConnections.valueAt(ic);
2674                for (int i=0; i<r.size(); i++) {
2675                    ConnectionRecord cr = r.get(i);
2676                    if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
2677                        continue;
2678                    }
2679                    if (dumpPackage != null && (cr.binding.client == null
2680                            || !dumpPackage.equals(cr.binding.client.info.packageName))) {
2681                        continue;
2682                    }
2683                    printedAnything = true;
2684                    if (!printed) {
2685                        if (needSep) pw.println();
2686                        needSep = true;
2687                        pw.println("  Connection bindings to services:");
2688                        printed = true;
2689                    }
2690                    pw.print("  * "); pw.println(cr);
2691                    cr.dump(pw, "    ");
2692                }
2693            }
2694        }
2695
2696        if (!printedAnything) {
2697            pw.println("  (nothing)");
2698        }
2699    }
2700
2701    /**
2702     * There are three ways to call this:
2703     *  - no service specified: dump all the services
2704     *  - a flattened component name that matched an existing service was specified as the
2705     *    first arg: dump that one service
2706     *  - the first arg isn't the flattened component name of an existing service:
2707     *    dump all services whose component contains the first arg as a substring
2708     */
2709    protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
2710            int opti, boolean dumpAll) {
2711        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
2712
2713        synchronized (mAm) {
2714            int[] users = mAm.getUsersLocked();
2715            if ("all".equals(name)) {
2716                for (int user : users) {
2717                    ServiceMap smap = mServiceMap.get(user);
2718                    if (smap == null) {
2719                        continue;
2720                    }
2721                    ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
2722                    for (int i=0; i<alls.size(); i++) {
2723                        ServiceRecord r1 = alls.valueAt(i);
2724                        services.add(r1);
2725                    }
2726                }
2727            } else {
2728                ComponentName componentName = name != null
2729                        ? ComponentName.unflattenFromString(name) : null;
2730                int objectId = 0;
2731                if (componentName == null) {
2732                    // Not a '/' separated full component name; maybe an object ID?
2733                    try {
2734                        objectId = Integer.parseInt(name, 16);
2735                        name = null;
2736                        componentName = null;
2737                    } catch (RuntimeException e) {
2738                    }
2739                }
2740
2741                for (int user : users) {
2742                    ServiceMap smap = mServiceMap.get(user);
2743                    if (smap == null) {
2744                        continue;
2745                    }
2746                    ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
2747                    for (int i=0; i<alls.size(); i++) {
2748                        ServiceRecord r1 = alls.valueAt(i);
2749                        if (componentName != null) {
2750                            if (r1.name.equals(componentName)) {
2751                                services.add(r1);
2752                            }
2753                        } else if (name != null) {
2754                            if (r1.name.flattenToString().contains(name)) {
2755                                services.add(r1);
2756                            }
2757                        } else if (System.identityHashCode(r1) == objectId) {
2758                            services.add(r1);
2759                        }
2760                    }
2761                }
2762            }
2763        }
2764
2765        if (services.size() <= 0) {
2766            return false;
2767        }
2768
2769        boolean needSep = false;
2770        for (int i=0; i<services.size(); i++) {
2771            if (needSep) {
2772                pw.println();
2773            }
2774            needSep = true;
2775            dumpService("", fd, pw, services.get(i), args, dumpAll);
2776        }
2777        return true;
2778    }
2779
2780    /**
2781     * Invokes IApplicationThread.dumpService() on the thread of the specified service if
2782     * there is a thread associated with the service.
2783     */
2784    private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
2785            final ServiceRecord r, String[] args, boolean dumpAll) {
2786        String innerPrefix = prefix + "  ";
2787        synchronized (mAm) {
2788            pw.print(prefix); pw.print("SERVICE ");
2789                    pw.print(r.shortName); pw.print(" ");
2790                    pw.print(Integer.toHexString(System.identityHashCode(r)));
2791                    pw.print(" pid=");
2792                    if (r.app != null) pw.println(r.app.pid);
2793                    else pw.println("(not running)");
2794            if (dumpAll) {
2795                r.dump(pw, innerPrefix);
2796            }
2797        }
2798        if (r.app != null && r.app.thread != null) {
2799            pw.print(prefix); pw.println("  Client:");
2800            pw.flush();
2801            try {
2802                TransferPipe tp = new TransferPipe();
2803                try {
2804                    r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
2805                    tp.setBufferPrefix(prefix + "    ");
2806                    tp.go(fd);
2807                } finally {
2808                    tp.kill();
2809                }
2810            } catch (IOException e) {
2811                pw.println(prefix + "    Failure while dumping the service: " + e);
2812            } catch (RemoteException e) {
2813                pw.println(prefix + "    Got a RemoteException while dumping the service");
2814            }
2815        }
2816    }
2817
2818}
2819