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