ActiveServices.java revision 40c8725804f46c9d53f2815e0ee69e6cfb0152cc
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                        userId = 0;
993                        smap = getServiceMap(0);
994                    }
995                    sInfo = new ServiceInfo(sInfo);
996                    sInfo.applicationInfo = mAm.getAppInfoForUser(sInfo.applicationInfo, userId);
997                }
998                r = smap.mServicesByName.get(name);
999                if (r == null && createIfNeeded) {
1000                    Intent.FilterComparison filter
1001                            = new Intent.FilterComparison(service.cloneFilter());
1002                    ServiceRestarter res = new ServiceRestarter();
1003                    BatteryStatsImpl.Uid.Pkg.Serv ss = null;
1004                    BatteryStatsImpl stats = mAm.mBatteryStatsService.getActiveStatistics();
1005                    synchronized (stats) {
1006                        ss = stats.getServiceStatsLocked(
1007                                sInfo.applicationInfo.uid, sInfo.packageName,
1008                                sInfo.name);
1009                    }
1010                    r = new ServiceRecord(mAm, ss, name, filter, sInfo, callingFromFg, res);
1011                    res.setService(r);
1012                    smap.mServicesByName.put(name, r);
1013                    smap.mServicesByIntent.put(filter, r);
1014
1015                    // Make sure this component isn't in the pending list.
1016                    for (int i=mPendingServices.size()-1; i>=0; i--) {
1017                        ServiceRecord pr = mPendingServices.get(i);
1018                        if (pr.serviceInfo.applicationInfo.uid == sInfo.applicationInfo.uid
1019                                && pr.name.equals(name)) {
1020                            mPendingServices.remove(i);
1021                        }
1022                    }
1023                }
1024            } catch (RemoteException ex) {
1025                // pm is in same process, this will never happen.
1026            }
1027        }
1028        if (r != null) {
1029            if (mAm.checkComponentPermission(r.permission,
1030                    callingPid, callingUid, r.appInfo.uid, r.exported)
1031                    != PackageManager.PERMISSION_GRANTED) {
1032                if (!r.exported) {
1033                    Slog.w(TAG, "Permission Denial: Accessing service " + r.name
1034                            + " from pid=" + callingPid
1035                            + ", uid=" + callingUid
1036                            + " that is not exported from uid " + r.appInfo.uid);
1037                    return new ServiceLookupResult(null, "not exported from uid "
1038                            + r.appInfo.uid);
1039                }
1040                Slog.w(TAG, "Permission Denial: Accessing service " + r.name
1041                        + " from pid=" + callingPid
1042                        + ", uid=" + callingUid
1043                        + " requires " + r.permission);
1044                return new ServiceLookupResult(null, r.permission);
1045            }
1046            if (!mAm.mIntentFirewall.checkService(r.name, service, callingUid, callingPid,
1047                    resolvedType, r.appInfo)) {
1048                return null;
1049            }
1050            return new ServiceLookupResult(r, null);
1051        }
1052        return null;
1053    }
1054
1055    private final void bumpServiceExecutingLocked(ServiceRecord r, boolean fg, String why) {
1056        if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING "
1057                + why + " of " + r + " in app " + r.app);
1058        else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, ">>> EXECUTING "
1059                + why + " of " + r.shortName);
1060        long now = SystemClock.uptimeMillis();
1061        if (r.executeNesting == 0) {
1062            r.executeFg = fg;
1063            ProcessStats.ServiceState stracker = r.getTracker();
1064            if (stracker != null) {
1065                stracker.setExecuting(true, mAm.mProcessStats.getMemFactorLocked(), now);
1066            }
1067            if (r.app != null) {
1068                r.app.executingServices.add(r);
1069                r.app.execServicesFg |= fg;
1070                if (r.app.executingServices.size() == 1) {
1071                    scheduleServiceTimeoutLocked(r.app);
1072                }
1073            }
1074        } else if (r.app != null && fg && !r.app.execServicesFg) {
1075            r.app.execServicesFg = true;
1076            scheduleServiceTimeoutLocked(r.app);
1077        }
1078        r.executeFg |= fg;
1079        r.executeNesting++;
1080        r.executingStart = now;
1081    }
1082
1083    private final boolean requestServiceBindingLocked(ServiceRecord r,
1084            IntentBindRecord i, boolean execInFg, boolean rebind) {
1085        if (r.app == null || r.app.thread == null) {
1086            // If service is not currently running, can't yet bind.
1087            return false;
1088        }
1089        if ((!i.requested || rebind) && i.apps.size() > 0) {
1090            try {
1091                bumpServiceExecutingLocked(r, execInFg, "bind");
1092                r.app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
1093                r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind,
1094                        r.app.repProcState);
1095                if (!rebind) {
1096                    i.requested = true;
1097                }
1098                i.hasBound = true;
1099                i.doRebind = false;
1100            } catch (RemoteException e) {
1101                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while binding " + r);
1102                return false;
1103            }
1104        }
1105        return true;
1106    }
1107
1108    private final boolean scheduleServiceRestartLocked(ServiceRecord r,
1109            boolean allowCancel) {
1110        boolean canceled = false;
1111
1112        ServiceMap smap = getServiceMap(r.userId);
1113        if (smap.mServicesByName.get(r.name) != r) {
1114            ServiceRecord cur = smap.mServicesByName.get(r.name);
1115            Slog.wtf(TAG, "Attempting to schedule restart of " + r
1116                    + " when found in map: " + cur);
1117            return false;
1118        }
1119
1120        final long now = SystemClock.uptimeMillis();
1121
1122        if ((r.serviceInfo.applicationInfo.flags
1123                &ApplicationInfo.FLAG_PERSISTENT) == 0) {
1124            long minDuration = SERVICE_RESTART_DURATION;
1125            long resetTime = SERVICE_RESET_RUN_DURATION;
1126
1127            // Any delivered but not yet finished starts should be put back
1128            // on the pending list.
1129            final int N = r.deliveredStarts.size();
1130            if (N > 0) {
1131                for (int i=N-1; i>=0; i--) {
1132                    ServiceRecord.StartItem si = r.deliveredStarts.get(i);
1133                    si.removeUriPermissionsLocked();
1134                    if (si.intent == null) {
1135                        // We'll generate this again if needed.
1136                    } else if (!allowCancel || (si.deliveryCount < ServiceRecord.MAX_DELIVERY_COUNT
1137                            && si.doneExecutingCount < ServiceRecord.MAX_DONE_EXECUTING_COUNT)) {
1138                        r.pendingStarts.add(0, si);
1139                        long dur = SystemClock.uptimeMillis() - si.deliveredTime;
1140                        dur *= 2;
1141                        if (minDuration < dur) minDuration = dur;
1142                        if (resetTime < dur) resetTime = dur;
1143                    } else {
1144                        Slog.w(TAG, "Canceling start item " + si.intent + " in service "
1145                                + r.name);
1146                        canceled = true;
1147                    }
1148                }
1149                r.deliveredStarts.clear();
1150            }
1151
1152            r.totalRestartCount++;
1153            if (r.restartDelay == 0) {
1154                r.restartCount++;
1155                r.restartDelay = minDuration;
1156            } else {
1157                // If it has been a "reasonably long time" since the service
1158                // was started, then reset our restart duration back to
1159                // the beginning, so we don't infinitely increase the duration
1160                // on a service that just occasionally gets killed (which is
1161                // a normal case, due to process being killed to reclaim memory).
1162                if (now > (r.restartTime+resetTime)) {
1163                    r.restartCount = 1;
1164                    r.restartDelay = minDuration;
1165                } else {
1166                    r.restartDelay *= SERVICE_RESTART_DURATION_FACTOR;
1167                    if (r.restartDelay < minDuration) {
1168                        r.restartDelay = minDuration;
1169                    }
1170                }
1171            }
1172
1173            r.nextRestartTime = now + r.restartDelay;
1174
1175            // Make sure that we don't end up restarting a bunch of services
1176            // all at the same time.
1177            boolean repeat;
1178            do {
1179                repeat = false;
1180                for (int i=mRestartingServices.size()-1; i>=0; i--) {
1181                    ServiceRecord r2 = mRestartingServices.get(i);
1182                    if (r2 != r && r.nextRestartTime
1183                            >= (r2.nextRestartTime-SERVICE_MIN_RESTART_TIME_BETWEEN)
1184                            && r.nextRestartTime
1185                            < (r2.nextRestartTime+SERVICE_MIN_RESTART_TIME_BETWEEN)) {
1186                        r.nextRestartTime = r2.nextRestartTime + SERVICE_MIN_RESTART_TIME_BETWEEN;
1187                        r.restartDelay = r.nextRestartTime - now;
1188                        repeat = true;
1189                        break;
1190                    }
1191                }
1192            } while (repeat);
1193
1194        } else {
1195            // Persistent processes are immediately restarted, so there is no
1196            // reason to hold of on restarting their services.
1197            r.totalRestartCount++;
1198            r.restartCount = 0;
1199            r.restartDelay = 0;
1200            r.nextRestartTime = now;
1201        }
1202
1203        if (!mRestartingServices.contains(r)) {
1204            r.createdFromFg = false;
1205            mRestartingServices.add(r);
1206            r.makeRestarting(mAm.mProcessStats.getMemFactorLocked(), now);
1207        }
1208
1209        r.cancelNotification();
1210
1211        mAm.mHandler.removeCallbacks(r.restarter);
1212        mAm.mHandler.postAtTime(r.restarter, r.nextRestartTime);
1213        r.nextRestartTime = SystemClock.uptimeMillis() + r.restartDelay;
1214        Slog.w(TAG, "Scheduling restart of crashed service "
1215                + r.shortName + " in " + r.restartDelay + "ms");
1216        EventLog.writeEvent(EventLogTags.AM_SCHEDULE_SERVICE_RESTART,
1217                r.userId, r.shortName, r.restartDelay);
1218
1219        return canceled;
1220    }
1221
1222    final void performServiceRestartLocked(ServiceRecord r) {
1223        if (!mRestartingServices.contains(r)) {
1224            return;
1225        }
1226        bringUpServiceLocked(r, r.intent.getIntent().getFlags(), r.createdFromFg, true);
1227    }
1228
1229    private final boolean unscheduleServiceRestartLocked(ServiceRecord r, int callingUid,
1230            boolean force) {
1231        if (!force && r.restartDelay == 0) {
1232            return false;
1233        }
1234        // Remove from the restarting list; if the service is currently on the
1235        // restarting list, or the call is coming from another app, then this
1236        // service has become of much more interest so we reset the restart interval.
1237        boolean removed = mRestartingServices.remove(r);
1238        if (removed || callingUid != r.appInfo.uid) {
1239            r.resetRestartCounter();
1240        }
1241        if (removed) {
1242            clearRestartingIfNeededLocked(r);
1243        }
1244        mAm.mHandler.removeCallbacks(r.restarter);
1245        return true;
1246    }
1247
1248    private void clearRestartingIfNeededLocked(ServiceRecord r) {
1249        if (r.restartTracker != null) {
1250            // If this is the last restarting record with this tracker, then clear
1251            // the tracker's restarting state.
1252            boolean stillTracking = false;
1253            for (int i=mRestartingServices.size()-1; i>=0; i--) {
1254                if (mRestartingServices.get(i).restartTracker == r.restartTracker) {
1255                    stillTracking = true;
1256                    break;
1257                }
1258            }
1259            if (!stillTracking) {
1260                r.restartTracker.setRestarting(false, mAm.mProcessStats.getMemFactorLocked(),
1261                        SystemClock.uptimeMillis());
1262                r.restartTracker = null;
1263            }
1264        }
1265    }
1266
1267    private final String bringUpServiceLocked(ServiceRecord r,
1268            int intentFlags, boolean execInFg, boolean whileRestarting) {
1269        //Slog.i(TAG, "Bring up service:");
1270        //r.dump("  ");
1271
1272        if (r.app != null && r.app.thread != null) {
1273            sendServiceArgsLocked(r, execInFg, false);
1274            return null;
1275        }
1276
1277        if (!whileRestarting && r.restartDelay > 0) {
1278            // If waiting for a restart, then do nothing.
1279            return null;
1280        }
1281
1282        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing up " + r + " " + r.intent);
1283
1284        // We are now bringing the service up, so no longer in the
1285        // restarting state.
1286        if (mRestartingServices.remove(r)) {
1287            clearRestartingIfNeededLocked(r);
1288        }
1289
1290        // Make sure this service is no longer considered delayed, we are starting it now.
1291        if (r.delayed) {
1292            if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "REM FR DELAY LIST (bring up): " + r);
1293            getServiceMap(r.userId).mDelayedStartList.remove(r);
1294            r.delayed = false;
1295        }
1296
1297        // Make sure that the user who owns this service is started.  If not,
1298        // we don't want to allow it to run.
1299        if (mAm.mStartedUsers.get(r.userId) == null) {
1300            String msg = "Unable to launch app "
1301                    + r.appInfo.packageName + "/"
1302                    + r.appInfo.uid + " for service "
1303                    + r.intent.getIntent() + ": user " + r.userId + " is stopped";
1304            Slog.w(TAG, msg);
1305            bringDownServiceLocked(r);
1306            return msg;
1307        }
1308
1309        // Service is now being launched, its package can't be stopped.
1310        try {
1311            AppGlobals.getPackageManager().setPackageStoppedState(
1312                    r.packageName, false, r.userId);
1313        } catch (RemoteException e) {
1314        } catch (IllegalArgumentException e) {
1315            Slog.w(TAG, "Failed trying to unstop package "
1316                    + r.packageName + ": " + e);
1317        }
1318
1319        final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0;
1320        final String procName = r.processName;
1321        ProcessRecord app;
1322
1323        if (!isolated) {
1324            app = mAm.getProcessRecordLocked(procName, r.appInfo.uid, false);
1325            if (DEBUG_MU) Slog.v(TAG_MU, "bringUpServiceLocked: appInfo.uid=" + r.appInfo.uid
1326                        + " app=" + app);
1327            if (app != null && app.thread != null) {
1328                try {
1329                    app.addPackage(r.appInfo.packageName, mAm.mProcessStats);
1330                    realStartServiceLocked(r, app, execInFg);
1331                    return null;
1332                } catch (RemoteException e) {
1333                    Slog.w(TAG, "Exception when starting service " + r.shortName, e);
1334                }
1335
1336                // If a dead object exception was thrown -- fall through to
1337                // restart the application.
1338            }
1339        } else {
1340            // If this service runs in an isolated process, then each time
1341            // we call startProcessLocked() we will get a new isolated
1342            // process, starting another process if we are currently waiting
1343            // for a previous process to come up.  To deal with this, we store
1344            // in the service any current isolated process it is running in or
1345            // waiting to have come up.
1346            app = r.isolatedProc;
1347        }
1348
1349        // Not running -- get it started, and enqueue this service record
1350        // to be executed when the app comes up.
1351        if (app == null) {
1352            if ((app=mAm.startProcessLocked(procName, r.appInfo, true, intentFlags,
1353                    "service", r.name, false, isolated, false)) == null) {
1354                String msg = "Unable to launch app "
1355                        + r.appInfo.packageName + "/"
1356                        + r.appInfo.uid + " for service "
1357                        + r.intent.getIntent() + ": process is bad";
1358                Slog.w(TAG, msg);
1359                bringDownServiceLocked(r);
1360                return msg;
1361            }
1362            if (isolated) {
1363                r.isolatedProc = app;
1364            }
1365        }
1366
1367        if (!mPendingServices.contains(r)) {
1368            mPendingServices.add(r);
1369        }
1370
1371        if (r.delayedStop) {
1372            // Oh and hey we've already been asked to stop!
1373            r.delayedStop = false;
1374            if (r.startRequested) {
1375                if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Applying delayed stop (in bring up): " + r);
1376                stopServiceLocked(r);
1377            }
1378        }
1379
1380        return null;
1381    }
1382
1383    private final void requestServiceBindingsLocked(ServiceRecord r, boolean execInFg) {
1384        for (int i=r.bindings.size()-1; i>=0; i--) {
1385            IntentBindRecord ibr = r.bindings.valueAt(i);
1386            if (!requestServiceBindingLocked(r, ibr, execInFg, false)) {
1387                break;
1388            }
1389        }
1390    }
1391
1392    private final void realStartServiceLocked(ServiceRecord r,
1393            ProcessRecord app, boolean execInFg) throws RemoteException {
1394        if (app.thread == null) {
1395            throw new RemoteException();
1396        }
1397        if (DEBUG_MU)
1398            Slog.v(TAG_MU, "realStartServiceLocked, ServiceRecord.uid = " + r.appInfo.uid
1399                    + ", ProcessRecord.uid = " + app.uid);
1400        r.app = app;
1401        r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
1402
1403        app.services.add(r);
1404        bumpServiceExecutingLocked(r, execInFg, "create");
1405        mAm.updateLruProcessLocked(app, false, null);
1406        mAm.updateOomAdjLocked();
1407
1408        boolean created = false;
1409        try {
1410            String nameTerm;
1411            int lastPeriod = r.shortName.lastIndexOf('.');
1412            nameTerm = lastPeriod >= 0 ? r.shortName.substring(lastPeriod) : r.shortName;
1413            EventLogTags.writeAmCreateService(
1414                    r.userId, System.identityHashCode(r), nameTerm, r.app.uid, r.app.pid);
1415            synchronized (r.stats.getBatteryStats()) {
1416                r.stats.startLaunchedLocked();
1417            }
1418            mAm.ensurePackageDexOpt(r.serviceInfo.packageName);
1419            app.forceProcessStateUpTo(ActivityManager.PROCESS_STATE_SERVICE);
1420            app.thread.scheduleCreateService(r, r.serviceInfo,
1421                    mAm.compatibilityInfoForPackageLocked(r.serviceInfo.applicationInfo),
1422                    app.repProcState);
1423            r.postNotification();
1424            created = true;
1425        } finally {
1426            if (!created) {
1427                app.services.remove(r);
1428                r.app = null;
1429                scheduleServiceRestartLocked(r, false);
1430            }
1431        }
1432
1433        requestServiceBindingsLocked(r, execInFg);
1434
1435        // If the service is in the started state, and there are no
1436        // pending arguments, then fake up one so its onStartCommand() will
1437        // be called.
1438        if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
1439            r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
1440                    null, null));
1441        }
1442
1443        sendServiceArgsLocked(r, execInFg, true);
1444
1445        if (r.delayed) {
1446            if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "REM FR DELAY LIST (new proc): " + r);
1447            getServiceMap(r.userId).mDelayedStartList.remove(r);
1448            r.delayed = false;
1449        }
1450
1451        if (r.delayedStop) {
1452            // Oh and hey we've already been asked to stop!
1453            r.delayedStop = false;
1454            if (r.startRequested) {
1455                if (DEBUG_DELAYED_STARTS) Slog.v(TAG, "Applying delayed stop (from start): " + r);
1456                stopServiceLocked(r);
1457            }
1458        }
1459    }
1460
1461    private final void sendServiceArgsLocked(ServiceRecord r, boolean execInFg,
1462            boolean oomAdjusted) {
1463        final int N = r.pendingStarts.size();
1464        if (N == 0) {
1465            return;
1466        }
1467
1468        while (r.pendingStarts.size() > 0) {
1469            try {
1470                ServiceRecord.StartItem si = r.pendingStarts.remove(0);
1471                if (DEBUG_SERVICE) Slog.v(TAG, "Sending arguments to: "
1472                        + r + " " + r.intent + " args=" + si.intent);
1473                if (si.intent == null && N > 1) {
1474                    // If somehow we got a dummy null intent in the middle,
1475                    // then skip it.  DO NOT skip a null intent when it is
1476                    // the only one in the list -- this is to support the
1477                    // onStartCommand(null) case.
1478                    continue;
1479                }
1480                si.deliveredTime = SystemClock.uptimeMillis();
1481                r.deliveredStarts.add(si);
1482                si.deliveryCount++;
1483                if (si.neededGrants != null) {
1484                    mAm.grantUriPermissionUncheckedFromIntentLocked(si.neededGrants,
1485                            si.getUriPermissionsLocked());
1486                }
1487                bumpServiceExecutingLocked(r, execInFg, "start");
1488                if (!oomAdjusted) {
1489                    oomAdjusted = true;
1490                    mAm.updateOomAdjLocked(r.app);
1491                }
1492                int flags = 0;
1493                if (si.deliveryCount > 1) {
1494                    flags |= Service.START_FLAG_RETRY;
1495                }
1496                if (si.doneExecutingCount > 0) {
1497                    flags |= Service.START_FLAG_REDELIVERY;
1498                }
1499                r.app.thread.scheduleServiceArgs(r, si.taskRemoved, si.id, flags, si.intent);
1500            } catch (RemoteException e) {
1501                // Remote process gone...  we'll let the normal cleanup take
1502                // care of this.
1503                if (DEBUG_SERVICE) Slog.v(TAG, "Crashed while scheduling start: " + r);
1504                break;
1505            } catch (Exception e) {
1506                Slog.w(TAG, "Unexpected exception", e);
1507                break;
1508            }
1509        }
1510    }
1511
1512    private final boolean isServiceNeeded(ServiceRecord r, boolean knowConn, boolean hasConn) {
1513        // Are we still explicitly being asked to run?
1514        if (r.startRequested) {
1515            return true;
1516        }
1517
1518        // Is someone still bound to us keepign us running?
1519        if (!knowConn) {
1520            hasConn = r.hasAutoCreateConnections();
1521        }
1522        if (hasConn) {
1523            return true;
1524        }
1525
1526        return false;
1527    }
1528
1529    private final void bringDownServiceIfNeededLocked(ServiceRecord r, boolean knowConn,
1530            boolean hasConn) {
1531        //Slog.i(TAG, "Bring down service:");
1532        //r.dump("  ");
1533
1534        if (isServiceNeeded(r, knowConn, hasConn)) {
1535            return;
1536        }
1537
1538        // Are we in the process of launching?
1539        if (mPendingServices.contains(r)) {
1540            return;
1541        }
1542
1543        bringDownServiceLocked(r);
1544    }
1545
1546    private final void bringDownServiceLocked(ServiceRecord r) {
1547        //Slog.i(TAG, "Bring down service:");
1548        //r.dump("  ");
1549
1550        // Report to all of the connections that the service is no longer
1551        // available.
1552        for (int conni=r.connections.size()-1; conni>=0; conni--) {
1553            ArrayList<ConnectionRecord> c = r.connections.valueAt(conni);
1554            for (int i=0; i<c.size(); i++) {
1555                ConnectionRecord cr = c.get(i);
1556                // There is still a connection to the service that is
1557                // being brought down.  Mark it as dead.
1558                cr.serviceDead = true;
1559                try {
1560                    cr.conn.connected(r.name, null);
1561                } catch (Exception e) {
1562                    Slog.w(TAG, "Failure disconnecting service " + r.name +
1563                          " to connection " + c.get(i).conn.asBinder() +
1564                          " (in " + c.get(i).binding.client.processName + ")", e);
1565                }
1566            }
1567        }
1568
1569        // Tell the service that it has been unbound.
1570        if (r.app != null && r.app.thread != null) {
1571            for (int i=r.bindings.size()-1; i>=0; i--) {
1572                IntentBindRecord ibr = r.bindings.valueAt(i);
1573                if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down binding " + ibr
1574                        + ": hasBound=" + ibr.hasBound);
1575                if (ibr.hasBound) {
1576                    try {
1577                        bumpServiceExecutingLocked(r, false, "bring down unbind");
1578                        mAm.updateOomAdjLocked(r.app);
1579                        ibr.hasBound = false;
1580                        r.app.thread.scheduleUnbindService(r,
1581                                ibr.intent.getIntent());
1582                    } catch (Exception e) {
1583                        Slog.w(TAG, "Exception when unbinding service "
1584                                + r.shortName, e);
1585                        serviceProcessGoneLocked(r);
1586                    }
1587                }
1588            }
1589        }
1590
1591        if (DEBUG_SERVICE) Slog.v(TAG, "Bringing down " + r + " " + r.intent);
1592        EventLogTags.writeAmDestroyService(
1593                r.userId, System.identityHashCode(r), (r.app != null) ? r.app.pid : -1);
1594
1595        final ServiceMap smap = getServiceMap(r.userId);
1596        smap.mServicesByName.remove(r.name);
1597        smap.mServicesByIntent.remove(r.intent);
1598        r.totalRestartCount = 0;
1599        unscheduleServiceRestartLocked(r, 0, true);
1600
1601        // Also make sure it is not on the pending list.
1602        for (int i=mPendingServices.size()-1; i>=0; i--) {
1603            if (mPendingServices.get(i) == r) {
1604                mPendingServices.remove(i);
1605                if (DEBUG_SERVICE) Slog.v(TAG, "Removed pending: " + r);
1606            }
1607        }
1608
1609        r.cancelNotification();
1610        r.isForeground = false;
1611        r.foregroundId = 0;
1612        r.foregroundNoti = null;
1613
1614        // Clear start entries.
1615        r.clearDeliveredStartsLocked();
1616        r.pendingStarts.clear();
1617
1618        if (r.app != null) {
1619            synchronized (r.stats.getBatteryStats()) {
1620                r.stats.stopLaunchedLocked();
1621            }
1622            r.app.services.remove(r);
1623            if (r.app.thread != null) {
1624                updateServiceForegroundLocked(r.app, false);
1625                try {
1626                    bumpServiceExecutingLocked(r, false, "destroy");
1627                    mDestroyingServices.add(r);
1628                    mAm.updateOomAdjLocked(r.app);
1629                    r.app.thread.scheduleStopService(r);
1630                } catch (Exception e) {
1631                    Slog.w(TAG, "Exception when destroying service "
1632                            + r.shortName, e);
1633                    serviceProcessGoneLocked(r);
1634                }
1635            } else {
1636                if (DEBUG_SERVICE) Slog.v(
1637                    TAG, "Removed service that has no process: " + r);
1638            }
1639        } else {
1640            if (DEBUG_SERVICE) Slog.v(
1641                TAG, "Removed service that is not running: " + r);
1642        }
1643
1644        if (r.bindings.size() > 0) {
1645            r.bindings.clear();
1646        }
1647
1648        if (r.restarter instanceof ServiceRestarter) {
1649           ((ServiceRestarter)r.restarter).setService(null);
1650        }
1651
1652        int memFactor = mAm.mProcessStats.getMemFactorLocked();
1653        long now = SystemClock.uptimeMillis();
1654        if (r.tracker != null) {
1655            r.tracker.setStarted(false, memFactor, now);
1656            r.tracker.setBound(false, memFactor, now);
1657            if (r.executeNesting == 0) {
1658                r.tracker.clearCurrentOwner(r, false);
1659                r.tracker = null;
1660            }
1661        }
1662
1663        smap.ensureNotStartingBackground(r);
1664    }
1665
1666    void removeConnectionLocked(
1667        ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct) {
1668        IBinder binder = c.conn.asBinder();
1669        AppBindRecord b = c.binding;
1670        ServiceRecord s = b.service;
1671        ArrayList<ConnectionRecord> clist = s.connections.get(binder);
1672        if (clist != null) {
1673            clist.remove(c);
1674            if (clist.size() == 0) {
1675                s.connections.remove(binder);
1676            }
1677        }
1678        b.connections.remove(c);
1679        if (c.activity != null && c.activity != skipAct) {
1680            if (c.activity.connections != null) {
1681                c.activity.connections.remove(c);
1682            }
1683        }
1684        if (b.client != skipApp) {
1685            b.client.connections.remove(c);
1686            if ((c.flags&Context.BIND_ABOVE_CLIENT) != 0) {
1687                b.client.updateHasAboveClientLocked();
1688            }
1689            if (s.app != null) {
1690                updateServiceClientActivitiesLocked(s.app, c);
1691            }
1692        }
1693        clist = mServiceConnections.get(binder);
1694        if (clist != null) {
1695            clist.remove(c);
1696            if (clist.size() == 0) {
1697                mServiceConnections.remove(binder);
1698            }
1699        }
1700
1701        if (b.connections.size() == 0) {
1702            b.intent.apps.remove(b.client);
1703        }
1704
1705        if (!c.serviceDead) {
1706            if (DEBUG_SERVICE) Slog.v(TAG, "Disconnecting binding " + b.intent
1707                    + ": shouldUnbind=" + b.intent.hasBound);
1708            if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
1709                    && b.intent.hasBound) {
1710                try {
1711                    bumpServiceExecutingLocked(s, false, "unbind");
1712                    if (b.client != s.app && (c.flags&Context.BIND_WAIVE_PRIORITY) == 0
1713                            && s.app.setProcState <= ActivityManager.PROCESS_STATE_RECEIVER) {
1714                        // If this service's process is not already in the cached list,
1715                        // then update it in the LRU list here because this may be causing
1716                        // it to go down there and we want it to start out near the top.
1717                        mAm.updateLruProcessLocked(s.app, false, null);
1718                    }
1719                    mAm.updateOomAdjLocked(s.app);
1720                    b.intent.hasBound = false;
1721                    // Assume the client doesn't want to know about a rebind;
1722                    // we will deal with that later if it asks for one.
1723                    b.intent.doRebind = false;
1724                    s.app.thread.scheduleUnbindService(s, b.intent.intent.getIntent());
1725                } catch (Exception e) {
1726                    Slog.w(TAG, "Exception when unbinding service " + s.shortName, e);
1727                    serviceProcessGoneLocked(s);
1728                }
1729            }
1730
1731            if ((c.flags&Context.BIND_AUTO_CREATE) != 0) {
1732                boolean hasAutoCreate = s.hasAutoCreateConnections();
1733                if (!hasAutoCreate) {
1734                    if (s.tracker != null) {
1735                        s.tracker.setBound(false, mAm.mProcessStats.getMemFactorLocked(),
1736                                SystemClock.uptimeMillis());
1737                    }
1738                }
1739                bringDownServiceIfNeededLocked(s, true, hasAutoCreate);
1740            }
1741        }
1742    }
1743
1744    void serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res) {
1745        boolean inDestroying = mDestroyingServices.contains(r);
1746        if (r != null) {
1747            if (type == 1) {
1748                // This is a call from a service start...  take care of
1749                // book-keeping.
1750                r.callStart = true;
1751                switch (res) {
1752                    case Service.START_STICKY_COMPATIBILITY:
1753                    case Service.START_STICKY: {
1754                        // We are done with the associated start arguments.
1755                        r.findDeliveredStart(startId, true);
1756                        // Don't stop if killed.
1757                        r.stopIfKilled = false;
1758                        break;
1759                    }
1760                    case Service.START_NOT_STICKY: {
1761                        // We are done with the associated start arguments.
1762                        r.findDeliveredStart(startId, true);
1763                        if (r.getLastStartId() == startId) {
1764                            // There is no more work, and this service
1765                            // doesn't want to hang around if killed.
1766                            r.stopIfKilled = true;
1767                        }
1768                        break;
1769                    }
1770                    case Service.START_REDELIVER_INTENT: {
1771                        // We'll keep this item until they explicitly
1772                        // call stop for it, but keep track of the fact
1773                        // that it was delivered.
1774                        ServiceRecord.StartItem si = r.findDeliveredStart(startId, false);
1775                        if (si != null) {
1776                            si.deliveryCount = 0;
1777                            si.doneExecutingCount++;
1778                            // Don't stop if killed.
1779                            r.stopIfKilled = true;
1780                        }
1781                        break;
1782                    }
1783                    case Service.START_TASK_REMOVED_COMPLETE: {
1784                        // Special processing for onTaskRemoved().  Don't
1785                        // impact normal onStartCommand() processing.
1786                        r.findDeliveredStart(startId, true);
1787                        break;
1788                    }
1789                    default:
1790                        throw new IllegalArgumentException(
1791                                "Unknown service start result: " + res);
1792                }
1793                if (res == Service.START_STICKY_COMPATIBILITY) {
1794                    r.callStart = false;
1795                }
1796            }
1797            final long origId = Binder.clearCallingIdentity();
1798            serviceDoneExecutingLocked(r, inDestroying, inDestroying);
1799            Binder.restoreCallingIdentity(origId);
1800        } else {
1801            Slog.w(TAG, "Done executing unknown service from pid "
1802                    + Binder.getCallingPid());
1803        }
1804    }
1805
1806    private void serviceProcessGoneLocked(ServiceRecord r) {
1807        if (r.tracker != null) {
1808            int memFactor = mAm.mProcessStats.getMemFactorLocked();
1809            long now = SystemClock.uptimeMillis();
1810            r.tracker.setExecuting(false, memFactor, now);
1811            r.tracker.setBound(false, memFactor, now);
1812            r.tracker.setStarted(false, memFactor, now);
1813        }
1814        serviceDoneExecutingLocked(r, true, true);
1815    }
1816
1817    private void serviceDoneExecutingLocked(ServiceRecord r, boolean inDestroying,
1818            boolean finishing) {
1819        if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
1820                + ": nesting=" + r.executeNesting
1821                + ", inDestroying=" + inDestroying + ", app=" + r.app);
1822        else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
1823        r.executeNesting--;
1824        if (r.executeNesting <= 0) {
1825            if (r.app != null) {
1826                if (DEBUG_SERVICE) Slog.v(TAG,
1827                        "Nesting at 0 of " + r.shortName);
1828                r.app.execServicesFg = false;
1829                r.app.executingServices.remove(r);
1830                if (r.app.executingServices.size() == 0) {
1831                    if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
1832                            "No more executingServices of " + r.shortName);
1833                    mAm.mHandler.removeMessages(ActivityManagerService.SERVICE_TIMEOUT_MSG, r.app);
1834                } else if (r.executeFg) {
1835                    // Need to re-evaluate whether the app still needs to be in the foreground.
1836                    for (int i=r.app.executingServices.size()-1; i>=0; i--) {
1837                        if (r.app.executingServices.valueAt(i).executeFg) {
1838                            r.app.execServicesFg = true;
1839                            break;
1840                        }
1841                    }
1842                }
1843                if (inDestroying) {
1844                    if (DEBUG_SERVICE) Slog.v(TAG,
1845                            "doneExecuting remove destroying " + r);
1846                    mDestroyingServices.remove(r);
1847                    r.bindings.clear();
1848                }
1849                mAm.updateOomAdjLocked(r.app);
1850            }
1851            r.executeFg = false;
1852            if (r.tracker != null) {
1853                r.tracker.setExecuting(false, mAm.mProcessStats.getMemFactorLocked(),
1854                        SystemClock.uptimeMillis());
1855                if (finishing) {
1856                    r.tracker.clearCurrentOwner(r, false);
1857                    r.tracker = null;
1858                }
1859            }
1860            if (finishing) {
1861                if (r.app != null && !r.app.persistent) {
1862                    r.app.services.remove(r);
1863                }
1864                r.app = null;
1865            }
1866        }
1867    }
1868
1869    boolean attachApplicationLocked(ProcessRecord proc, String processName) throws Exception {
1870        boolean didSomething = false;
1871        // Collect any services that are waiting for this process to come up.
1872        if (mPendingServices.size() > 0) {
1873            ServiceRecord sr = null;
1874            try {
1875                for (int i=0; i<mPendingServices.size(); i++) {
1876                    sr = mPendingServices.get(i);
1877                    if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
1878                            || !processName.equals(sr.processName))) {
1879                        continue;
1880                    }
1881
1882                    mPendingServices.remove(i);
1883                    i--;
1884                    proc.addPackage(sr.appInfo.packageName, mAm.mProcessStats);
1885                    realStartServiceLocked(sr, proc, sr.createdFromFg);
1886                    didSomething = true;
1887                }
1888            } catch (Exception e) {
1889                Slog.w(TAG, "Exception in new application when starting service "
1890                        + sr.shortName, e);
1891                throw e;
1892            }
1893        }
1894        // Also, if there are any services that are waiting to restart and
1895        // would run in this process, now is a good time to start them.  It would
1896        // be weird to bring up the process but arbitrarily not let the services
1897        // run at this point just because their restart time hasn't come up.
1898        if (mRestartingServices.size() > 0) {
1899            ServiceRecord sr = null;
1900            for (int i=0; i<mRestartingServices.size(); i++) {
1901                sr = mRestartingServices.get(i);
1902                if (proc != sr.isolatedProc && (proc.uid != sr.appInfo.uid
1903                        || !processName.equals(sr.processName))) {
1904                    continue;
1905                }
1906                mAm.mHandler.removeCallbacks(sr.restarter);
1907                mAm.mHandler.post(sr.restarter);
1908            }
1909        }
1910        return didSomething;
1911    }
1912
1913    void processStartTimedOutLocked(ProcessRecord proc) {
1914        for (int i=0; i<mPendingServices.size(); i++) {
1915            ServiceRecord sr = mPendingServices.get(i);
1916            if ((proc.uid == sr.appInfo.uid
1917                    && proc.processName.equals(sr.processName))
1918                    || sr.isolatedProc == proc) {
1919                Slog.w(TAG, "Forcing bringing down service: " + sr);
1920                sr.isolatedProc = null;
1921                mPendingServices.remove(i);
1922                i--;
1923                bringDownServiceLocked(sr);
1924            }
1925        }
1926    }
1927
1928    private boolean collectForceStopServicesLocked(String name, int userId,
1929            boolean evenPersistent, boolean doit,
1930            ArrayMap<ComponentName, ServiceRecord> services,
1931            ArrayList<ServiceRecord> result) {
1932        boolean didSomething = false;
1933        for (int i=0; i<services.size(); i++) {
1934            ServiceRecord service = services.valueAt(i);
1935            if ((name == null || service.packageName.equals(name))
1936                    && (service.app == null || evenPersistent || !service.app.persistent)) {
1937                if (!doit) {
1938                    return true;
1939                }
1940                didSomething = true;
1941                Slog.i(TAG, "  Force stopping service " + service);
1942                if (service.app != null) {
1943                    service.app.removed = true;
1944                    if (!service.app.persistent) {
1945                        service.app.services.remove(service);
1946                    }
1947                }
1948                service.app = null;
1949                service.isolatedProc = null;
1950                result.add(service);
1951            }
1952        }
1953        return didSomething;
1954    }
1955
1956    boolean forceStopLocked(String name, int userId, boolean evenPersistent, boolean doit) {
1957        boolean didSomething = false;
1958        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
1959        if (userId == UserHandle.USER_ALL) {
1960            for (int i=0; i<mServiceMap.size(); i++) {
1961                didSomething |= collectForceStopServicesLocked(name, userId, evenPersistent,
1962                        doit, mServiceMap.valueAt(i).mServicesByName, services);
1963                if (!doit && didSomething) {
1964                    return true;
1965                }
1966            }
1967        } else {
1968            ServiceMap smap = mServiceMap.get(userId);
1969            if (smap != null) {
1970                ArrayMap<ComponentName, ServiceRecord> items = smap.mServicesByName;
1971                didSomething = collectForceStopServicesLocked(name, userId, evenPersistent,
1972                        doit, items, services);
1973            }
1974        }
1975
1976        int N = services.size();
1977        for (int i=0; i<N; i++) {
1978            bringDownServiceLocked(services.get(i));
1979        }
1980        return didSomething;
1981    }
1982
1983    void cleanUpRemovedTaskLocked(TaskRecord tr, ComponentName component, Intent baseIntent) {
1984        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
1985        ArrayMap<ComponentName, ServiceRecord> alls = getServices(tr.userId);
1986        for (int i=0; i<alls.size(); i++) {
1987            ServiceRecord sr = alls.valueAt(i);
1988            if (sr.packageName.equals(component.getPackageName())) {
1989                services.add(sr);
1990            }
1991        }
1992
1993        // Take care of any running services associated with the app.
1994        for (int i=0; i<services.size(); i++) {
1995            ServiceRecord sr = services.get(i);
1996            if (sr.startRequested) {
1997                if ((sr.serviceInfo.flags&ServiceInfo.FLAG_STOP_WITH_TASK) != 0) {
1998                    Slog.i(TAG, "Stopping service " + sr.shortName + ": remove task");
1999                    stopServiceLocked(sr);
2000                } else {
2001                    sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
2002                            sr.makeNextStartId(), baseIntent, null));
2003                    if (sr.app != null && sr.app.thread != null) {
2004                        // We always run in the foreground, since this is called as
2005                        // part of the "remove task" UI operation.
2006                        sendServiceArgsLocked(sr, true, false);
2007                    }
2008                }
2009            }
2010        }
2011    }
2012
2013    final void killServicesLocked(ProcessRecord app, boolean allowRestart) {
2014        // Report disconnected services.
2015        if (false) {
2016            // XXX we are letting the client link to the service for
2017            // death notifications.
2018            if (app.services.size() > 0) {
2019                Iterator<ServiceRecord> it = app.services.iterator();
2020                while (it.hasNext()) {
2021                    ServiceRecord r = it.next();
2022                    for (int conni=r.connections.size()-1; conni>=0; conni--) {
2023                        ArrayList<ConnectionRecord> cl = r.connections.valueAt(conni);
2024                        for (int i=0; i<cl.size(); i++) {
2025                            ConnectionRecord c = cl.get(i);
2026                            if (c.binding.client != app) {
2027                                try {
2028                                    //c.conn.connected(r.className, null);
2029                                } catch (Exception e) {
2030                                    // todo: this should be asynchronous!
2031                                    Slog.w(TAG, "Exception thrown disconnected servce "
2032                                          + r.shortName
2033                                          + " from app " + app.processName, e);
2034                                }
2035                            }
2036                        }
2037                    }
2038                }
2039            }
2040        }
2041
2042        // First clear app state from services.
2043        for (int i=app.services.size()-1; i>=0; i--) {
2044            ServiceRecord sr = app.services.valueAt(i);
2045            synchronized (sr.stats.getBatteryStats()) {
2046                sr.stats.stopLaunchedLocked();
2047            }
2048            if (sr.app != app && sr.app != null && !sr.app.persistent) {
2049                sr.app.services.remove(sr);
2050            }
2051            sr.app = null;
2052            sr.isolatedProc = null;
2053            sr.executeNesting = 0;
2054            sr.forceClearTracker();
2055            if (mDestroyingServices.remove(sr)) {
2056                if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove destroying " + sr);
2057            }
2058
2059            final int numClients = sr.bindings.size();
2060            for (int bindingi=numClients-1; bindingi>=0; bindingi--) {
2061                IntentBindRecord b = sr.bindings.valueAt(bindingi);
2062                if (DEBUG_SERVICE) Slog.v(TAG, "Killing binding " + b
2063                        + ": shouldUnbind=" + b.hasBound);
2064                b.binder = null;
2065                b.requested = b.received = b.hasBound = false;
2066            }
2067        }
2068
2069        // Clean up any connections this application has to other services.
2070        for (int i=app.connections.size()-1; i>=0; i--) {
2071            ConnectionRecord r = app.connections.valueAt(i);
2072            removeConnectionLocked(r, app, null);
2073        }
2074        app.connections.clear();
2075
2076        ServiceMap smap = getServiceMap(app.userId);
2077
2078        // Now do remaining service cleanup.
2079        for (int i=app.services.size()-1; i>=0; i--) {
2080            ServiceRecord sr = app.services.valueAt(i);
2081
2082            // Unless the process is persistent, this process record is going away,
2083            // so make sure the service is cleaned out of it.
2084            if (!app.persistent) {
2085                app.services.removeAt(i);
2086            }
2087
2088            // Sanity check: if the service listed for the app is not one
2089            // we actually are maintaining, just let it drop.
2090            final ServiceRecord curRec = smap.mServicesByName.get(sr.name);
2091            if (curRec != sr) {
2092                if (curRec != null) {
2093                    Slog.wtf(TAG, "Service " + sr + " in process " + app
2094                            + " not same as in map: " + curRec);
2095                }
2096                continue;
2097            }
2098
2099            // Any services running in the application may need to be placed
2100            // back in the pending list.
2101            if (allowRestart && sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags
2102                    &ApplicationInfo.FLAG_PERSISTENT) == 0) {
2103                Slog.w(TAG, "Service crashed " + sr.crashCount
2104                        + " times, stopping: " + sr);
2105                EventLog.writeEvent(EventLogTags.AM_SERVICE_CRASHED_TOO_MUCH,
2106                        sr.userId, sr.crashCount, sr.shortName, app.pid);
2107                bringDownServiceLocked(sr);
2108            } else if (!allowRestart) {
2109                bringDownServiceLocked(sr);
2110            } else {
2111                boolean canceled = scheduleServiceRestartLocked(sr, true);
2112
2113                // Should the service remain running?  Note that in the
2114                // extreme case of so many attempts to deliver a command
2115                // that it failed we also will stop it here.
2116                if (sr.startRequested && (sr.stopIfKilled || canceled)) {
2117                    if (sr.pendingStarts.size() == 0) {
2118                        sr.startRequested = false;
2119                        if (sr.tracker != null) {
2120                            sr.tracker.setStarted(false, mAm.mProcessStats.getMemFactorLocked(),
2121                                    SystemClock.uptimeMillis());
2122                        }
2123                        if (!sr.hasAutoCreateConnections()) {
2124                            // Whoops, no reason to restart!
2125                            bringDownServiceLocked(sr);
2126                        }
2127                    }
2128                }
2129            }
2130        }
2131
2132        if (!allowRestart) {
2133            app.services.clear();
2134
2135            // Make sure there are no more restarting services for this process.
2136            for (int i=mRestartingServices.size()-1; i>=0; i--) {
2137                ServiceRecord r = mRestartingServices.get(i);
2138                if (r.processName.equals(app.processName) &&
2139                        r.serviceInfo.applicationInfo.uid == app.info.uid) {
2140                    mRestartingServices.remove(i);
2141                    clearRestartingIfNeededLocked(r);
2142                }
2143            }
2144            for (int i=mPendingServices.size()-1; i>=0; i--) {
2145                ServiceRecord r = mPendingServices.get(i);
2146                if (r.processName.equals(app.processName) &&
2147                        r.serviceInfo.applicationInfo.uid == app.info.uid) {
2148                    mPendingServices.remove(i);
2149                }
2150            }
2151        }
2152
2153        // Make sure we have no more records on the stopping list.
2154        int i = mDestroyingServices.size();
2155        while (i > 0) {
2156            i--;
2157            ServiceRecord sr = mDestroyingServices.get(i);
2158            if (sr.app == app) {
2159                sr.forceClearTracker();
2160                mDestroyingServices.remove(i);
2161                if (DEBUG_SERVICE) Slog.v(TAG, "killServices remove destroying " + sr);
2162            }
2163        }
2164
2165        app.executingServices.clear();
2166    }
2167
2168    ActivityManager.RunningServiceInfo makeRunningServiceInfoLocked(ServiceRecord r) {
2169        ActivityManager.RunningServiceInfo info =
2170            new ActivityManager.RunningServiceInfo();
2171        info.service = r.name;
2172        if (r.app != null) {
2173            info.pid = r.app.pid;
2174        }
2175        info.uid = r.appInfo.uid;
2176        info.process = r.processName;
2177        info.foreground = r.isForeground;
2178        info.activeSince = r.createTime;
2179        info.started = r.startRequested;
2180        info.clientCount = r.connections.size();
2181        info.crashCount = r.crashCount;
2182        info.lastActivityTime = r.lastActivity;
2183        if (r.isForeground) {
2184            info.flags |= ActivityManager.RunningServiceInfo.FLAG_FOREGROUND;
2185        }
2186        if (r.startRequested) {
2187            info.flags |= ActivityManager.RunningServiceInfo.FLAG_STARTED;
2188        }
2189        if (r.app != null && r.app.pid == ActivityManagerService.MY_PID) {
2190            info.flags |= ActivityManager.RunningServiceInfo.FLAG_SYSTEM_PROCESS;
2191        }
2192        if (r.app != null && r.app.persistent) {
2193            info.flags |= ActivityManager.RunningServiceInfo.FLAG_PERSISTENT_PROCESS;
2194        }
2195
2196        for (int conni=r.connections.size()-1; conni>=0; conni--) {
2197            ArrayList<ConnectionRecord> connl = r.connections.valueAt(conni);
2198            for (int i=0; i<connl.size(); i++) {
2199                ConnectionRecord conn = connl.get(i);
2200                if (conn.clientLabel != 0) {
2201                    info.clientPackage = conn.binding.client.info.packageName;
2202                    info.clientLabel = conn.clientLabel;
2203                    return info;
2204                }
2205            }
2206        }
2207        return info;
2208    }
2209
2210    List<ActivityManager.RunningServiceInfo> getRunningServiceInfoLocked(int maxNum,
2211            int flags) {
2212        ArrayList<ActivityManager.RunningServiceInfo> res
2213                = new ArrayList<ActivityManager.RunningServiceInfo>();
2214
2215        final int uid = Binder.getCallingUid();
2216        final long ident = Binder.clearCallingIdentity();
2217        try {
2218            if (ActivityManager.checkUidPermission(
2219                    android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
2220                    uid) == PackageManager.PERMISSION_GRANTED) {
2221                int[] users = mAm.getUsersLocked();
2222                for (int ui=0; ui<users.length && res.size() < maxNum; ui++) {
2223                    ArrayMap<ComponentName, ServiceRecord> alls = getServices(users[ui]);
2224                    for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
2225                        ServiceRecord sr = alls.valueAt(i);
2226                        res.add(makeRunningServiceInfoLocked(sr));
2227                    }
2228                }
2229
2230                for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
2231                    ServiceRecord r = mRestartingServices.get(i);
2232                    ActivityManager.RunningServiceInfo info =
2233                            makeRunningServiceInfoLocked(r);
2234                    info.restarting = r.nextRestartTime;
2235                    res.add(info);
2236                }
2237            } else {
2238                int userId = UserHandle.getUserId(uid);
2239                ArrayMap<ComponentName, ServiceRecord> alls = getServices(userId);
2240                for (int i=0; i<alls.size() && res.size() < maxNum; i++) {
2241                    ServiceRecord sr = alls.valueAt(i);
2242                    res.add(makeRunningServiceInfoLocked(sr));
2243                }
2244
2245                for (int i=0; i<mRestartingServices.size() && res.size() < maxNum; i++) {
2246                    ServiceRecord r = mRestartingServices.get(i);
2247                    if (r.userId == userId) {
2248                        ActivityManager.RunningServiceInfo info =
2249                                makeRunningServiceInfoLocked(r);
2250                        info.restarting = r.nextRestartTime;
2251                        res.add(info);
2252                    }
2253                }
2254            }
2255        } finally {
2256            Binder.restoreCallingIdentity(ident);
2257        }
2258
2259        return res;
2260    }
2261
2262    public PendingIntent getRunningServiceControlPanelLocked(ComponentName name) {
2263        int userId = UserHandle.getUserId(Binder.getCallingUid());
2264        ServiceRecord r = getServiceByName(name, userId);
2265        if (r != null) {
2266            for (int conni=r.connections.size()-1; conni>=0; conni--) {
2267                ArrayList<ConnectionRecord> conn = r.connections.valueAt(conni);
2268                for (int i=0; i<conn.size(); i++) {
2269                    if (conn.get(i).clientIntent != null) {
2270                        return conn.get(i).clientIntent;
2271                    }
2272                }
2273            }
2274        }
2275        return null;
2276    }
2277
2278    void serviceTimeout(ProcessRecord proc) {
2279        String anrMessage = null;
2280
2281        synchronized(this) {
2282            if (proc.executingServices.size() == 0 || proc.thread == null) {
2283                return;
2284            }
2285            long maxTime = SystemClock.uptimeMillis() -
2286                    (proc.execServicesFg ? SERVICE_TIMEOUT : SERVICE_BACKGROUND_TIMEOUT);
2287            ServiceRecord timeout = null;
2288            long nextTime = 0;
2289            for (int i=proc.executingServices.size()-1; i>=0; i--) {
2290                ServiceRecord sr = proc.executingServices.valueAt(i);
2291                if (sr.executingStart < maxTime) {
2292                    timeout = sr;
2293                    break;
2294                }
2295                if (sr.executingStart > nextTime) {
2296                    nextTime = sr.executingStart;
2297                }
2298            }
2299            if (timeout != null && mAm.mLruProcesses.contains(proc)) {
2300                Slog.w(TAG, "Timeout executing service: " + timeout);
2301                anrMessage = "Executing service " + timeout.shortName;
2302            } else {
2303                Message msg = mAm.mHandler.obtainMessage(
2304                        ActivityManagerService.SERVICE_TIMEOUT_MSG);
2305                msg.obj = proc;
2306                mAm.mHandler.sendMessageAtTime(msg, proc.execServicesFg
2307                        ? (nextTime+SERVICE_TIMEOUT) : (nextTime + SERVICE_BACKGROUND_TIMEOUT));
2308            }
2309        }
2310
2311        if (anrMessage != null) {
2312            mAm.appNotResponding(proc, null, null, false, anrMessage);
2313        }
2314    }
2315
2316    void scheduleServiceTimeoutLocked(ProcessRecord proc) {
2317        if (proc.executingServices.size() == 0 || proc.thread == null) {
2318            return;
2319        }
2320        long now = SystemClock.uptimeMillis();
2321        Message msg = mAm.mHandler.obtainMessage(
2322                ActivityManagerService.SERVICE_TIMEOUT_MSG);
2323        msg.obj = proc;
2324        mAm.mHandler.sendMessageAtTime(msg,
2325                proc.execServicesFg ? (now+SERVICE_TIMEOUT) : (now+ SERVICE_BACKGROUND_TIMEOUT));
2326    }
2327
2328    /**
2329     * Prints a list of ServiceRecords (dumpsys activity services)
2330     */
2331    void dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
2332            int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
2333        boolean needSep = false;
2334        boolean printedAnything = false;
2335
2336        ItemMatcher matcher = new ItemMatcher();
2337        matcher.build(args, opti);
2338
2339        pw.println("ACTIVITY MANAGER SERVICES (dumpsys activity services)");
2340        try {
2341            int[] users = mAm.getUsersLocked();
2342            for (int user : users) {
2343                ServiceMap smap = getServiceMap(user);
2344                boolean printed = false;
2345                if (smap.mServicesByName.size() > 0) {
2346                    long nowReal = SystemClock.elapsedRealtime();
2347                    needSep = false;
2348                    for (int si=0; si<smap.mServicesByName.size(); si++) {
2349                        ServiceRecord r = smap.mServicesByName.valueAt(si);
2350                        if (!matcher.match(r, r.name)) {
2351                            continue;
2352                        }
2353                        if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2354                            continue;
2355                        }
2356                        if (!printed) {
2357                            if (printedAnything) {
2358                                pw.println();
2359                            }
2360                            pw.println("  User " + user + " active services:");
2361                            printed = true;
2362                        }
2363                        printedAnything = true;
2364                        if (needSep) {
2365                            pw.println();
2366                        }
2367                        pw.print("  * ");
2368                        pw.println(r);
2369                        if (dumpAll) {
2370                            r.dump(pw, "    ");
2371                            needSep = true;
2372                        } else {
2373                            pw.print("    app=");
2374                            pw.println(r.app);
2375                            pw.print("    created=");
2376                            TimeUtils.formatDuration(r.createTime, nowReal, pw);
2377                            pw.print(" started=");
2378                            pw.print(r.startRequested);
2379                            pw.print(" connections=");
2380                            pw.println(r.connections.size());
2381                            if (r.connections.size() > 0) {
2382                                pw.println("    Connections:");
2383                                for (int conni=0; conni<r.connections.size(); conni++) {
2384                                    ArrayList<ConnectionRecord> clist = r.connections.valueAt(conni);
2385                                    for (int i = 0; i < clist.size(); i++) {
2386                                        ConnectionRecord conn = clist.get(i);
2387                                        pw.print("      ");
2388                                        pw.print(conn.binding.intent.intent.getIntent()
2389                                                .toShortString(false, false, false, false));
2390                                        pw.print(" -> ");
2391                                        ProcessRecord proc = conn.binding.client;
2392                                        pw.println(proc != null ? proc.toShortString() : "null");
2393                                    }
2394                                }
2395                            }
2396                        }
2397                        if (dumpClient && r.app != null && r.app.thread != null) {
2398                            pw.println("    Client:");
2399                            pw.flush();
2400                            try {
2401                                TransferPipe tp = new TransferPipe();
2402                                try {
2403                                    r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(),
2404                                            r, args);
2405                                    tp.setBufferPrefix("      ");
2406                                    // Short timeout, since blocking here can
2407                                    // deadlock with the application.
2408                                    tp.go(fd, 2000);
2409                                } finally {
2410                                    tp.kill();
2411                                }
2412                            } catch (IOException e) {
2413                                pw.println("      Failure while dumping the service: " + e);
2414                            } catch (RemoteException e) {
2415                                pw.println("      Got a RemoteException while dumping the service");
2416                            }
2417                            needSep = true;
2418                        }
2419                    }
2420                    needSep |= printed;
2421                }
2422                printed = false;
2423                for (int si=0, SN=smap.mDelayedStartList.size(); si<SN; si++) {
2424                    ServiceRecord r = smap.mDelayedStartList.get(si);
2425                    if (!matcher.match(r, r.name)) {
2426                        continue;
2427                    }
2428                    if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2429                        continue;
2430                    }
2431                    if (!printed) {
2432                        if (printedAnything) {
2433                            pw.println();
2434                        }
2435                        pw.println("  User " + user + " delayed start services:");
2436                        printed = true;
2437                    }
2438                    printedAnything = true;
2439                    pw.print("  * Delayed start "); pw.println(r);
2440                }
2441                printed = false;
2442                for (int si=0, SN=smap.mStartingBackground.size(); si<SN; si++) {
2443                    ServiceRecord r = smap.mStartingBackground.get(si);
2444                    if (!matcher.match(r, r.name)) {
2445                        continue;
2446                    }
2447                    if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2448                        continue;
2449                    }
2450                    if (!printed) {
2451                        if (printedAnything) {
2452                            pw.println();
2453                        }
2454                        pw.println("  User " + user + " starting in background:");
2455                        printed = true;
2456                    }
2457                    printedAnything = true;
2458                    pw.print("  * Starting bg "); pw.println(r);
2459                }
2460            }
2461        } catch (Exception e) {
2462            Slog.w(TAG, "Exception in dumpServicesLocked", e);
2463        }
2464
2465        if (mPendingServices.size() > 0) {
2466            boolean printed = false;
2467            for (int i=0; i<mPendingServices.size(); i++) {
2468                ServiceRecord r = mPendingServices.get(i);
2469                if (!matcher.match(r, r.name)) {
2470                    continue;
2471                }
2472                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2473                    continue;
2474                }
2475                printedAnything = true;
2476                if (!printed) {
2477                    if (needSep) pw.println();
2478                    needSep = true;
2479                    pw.println("  Pending services:");
2480                    printed = true;
2481                }
2482                pw.print("  * Pending "); pw.println(r);
2483                r.dump(pw, "    ");
2484            }
2485            needSep = true;
2486        }
2487
2488        if (mRestartingServices.size() > 0) {
2489            boolean printed = false;
2490            for (int i=0; i<mRestartingServices.size(); i++) {
2491                ServiceRecord r = mRestartingServices.get(i);
2492                if (!matcher.match(r, r.name)) {
2493                    continue;
2494                }
2495                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2496                    continue;
2497                }
2498                printedAnything = true;
2499                if (!printed) {
2500                    if (needSep) pw.println();
2501                    needSep = true;
2502                    pw.println("  Restarting services:");
2503                    printed = true;
2504                }
2505                pw.print("  * Restarting "); pw.println(r);
2506                r.dump(pw, "    ");
2507            }
2508            needSep = true;
2509        }
2510
2511        if (mDestroyingServices.size() > 0) {
2512            boolean printed = false;
2513            for (int i=0; i< mDestroyingServices.size(); i++) {
2514                ServiceRecord r = mDestroyingServices.get(i);
2515                if (!matcher.match(r, r.name)) {
2516                    continue;
2517                }
2518                if (dumpPackage != null && !dumpPackage.equals(r.appInfo.packageName)) {
2519                    continue;
2520                }
2521                printedAnything = true;
2522                if (!printed) {
2523                    if (needSep) pw.println();
2524                    needSep = true;
2525                    pw.println("  Destroying services:");
2526                    printed = true;
2527                }
2528                pw.print("  * Destroy "); pw.println(r);
2529                r.dump(pw, "    ");
2530            }
2531            needSep = true;
2532        }
2533
2534        if (dumpAll) {
2535            boolean printed = false;
2536            for (int ic=0; ic<mServiceConnections.size(); ic++) {
2537                ArrayList<ConnectionRecord> r = mServiceConnections.valueAt(ic);
2538                for (int i=0; i<r.size(); i++) {
2539                    ConnectionRecord cr = r.get(i);
2540                    if (!matcher.match(cr.binding.service, cr.binding.service.name)) {
2541                        continue;
2542                    }
2543                    if (dumpPackage != null && (cr.binding.client == null
2544                            || !dumpPackage.equals(cr.binding.client.info.packageName))) {
2545                        continue;
2546                    }
2547                    printedAnything = true;
2548                    if (!printed) {
2549                        if (needSep) pw.println();
2550                        needSep = true;
2551                        pw.println("  Connection bindings to services:");
2552                        printed = true;
2553                    }
2554                    pw.print("  * "); pw.println(cr);
2555                    cr.dump(pw, "    ");
2556                }
2557            }
2558        }
2559
2560        if (!printedAnything) {
2561            pw.println("  (nothing)");
2562        }
2563    }
2564
2565    /**
2566     * There are three ways to call this:
2567     *  - no service specified: dump all the services
2568     *  - a flattened component name that matched an existing service was specified as the
2569     *    first arg: dump that one service
2570     *  - the first arg isn't the flattened component name of an existing service:
2571     *    dump all services whose component contains the first arg as a substring
2572     */
2573    protected boolean dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args,
2574            int opti, boolean dumpAll) {
2575        ArrayList<ServiceRecord> services = new ArrayList<ServiceRecord>();
2576
2577        synchronized (this) {
2578            int[] users = mAm.getUsersLocked();
2579            if ("all".equals(name)) {
2580                for (int user : users) {
2581                    ServiceMap smap = mServiceMap.get(user);
2582                    if (smap == null) {
2583                        continue;
2584                    }
2585                    ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
2586                    for (int i=0; i<alls.size(); i++) {
2587                        ServiceRecord r1 = alls.valueAt(i);
2588                        services.add(r1);
2589                    }
2590                }
2591            } else {
2592                ComponentName componentName = name != null
2593                        ? ComponentName.unflattenFromString(name) : null;
2594                int objectId = 0;
2595                if (componentName == null) {
2596                    // Not a '/' separated full component name; maybe an object ID?
2597                    try {
2598                        objectId = Integer.parseInt(name, 16);
2599                        name = null;
2600                        componentName = null;
2601                    } catch (RuntimeException e) {
2602                    }
2603                }
2604
2605                for (int user : users) {
2606                    ServiceMap smap = mServiceMap.get(user);
2607                    if (smap == null) {
2608                        continue;
2609                    }
2610                    ArrayMap<ComponentName, ServiceRecord> alls = smap.mServicesByName;
2611                    for (int i=0; i<alls.size(); i++) {
2612                        ServiceRecord r1 = alls.valueAt(i);
2613                        if (componentName != null) {
2614                            if (r1.name.equals(componentName)) {
2615                                services.add(r1);
2616                            }
2617                        } else if (name != null) {
2618                            if (r1.name.flattenToString().contains(name)) {
2619                                services.add(r1);
2620                            }
2621                        } else if (System.identityHashCode(r1) == objectId) {
2622                            services.add(r1);
2623                        }
2624                    }
2625                }
2626            }
2627        }
2628
2629        if (services.size() <= 0) {
2630            return false;
2631        }
2632
2633        boolean needSep = false;
2634        for (int i=0; i<services.size(); i++) {
2635            if (needSep) {
2636                pw.println();
2637            }
2638            needSep = true;
2639            dumpService("", fd, pw, services.get(i), args, dumpAll);
2640        }
2641        return true;
2642    }
2643
2644    /**
2645     * Invokes IApplicationThread.dumpService() on the thread of the specified service if
2646     * there is a thread associated with the service.
2647     */
2648    private void dumpService(String prefix, FileDescriptor fd, PrintWriter pw,
2649            final ServiceRecord r, String[] args, boolean dumpAll) {
2650        String innerPrefix = prefix + "  ";
2651        synchronized (this) {
2652            pw.print(prefix); pw.print("SERVICE ");
2653                    pw.print(r.shortName); pw.print(" ");
2654                    pw.print(Integer.toHexString(System.identityHashCode(r)));
2655                    pw.print(" pid=");
2656                    if (r.app != null) pw.println(r.app.pid);
2657                    else pw.println("(not running)");
2658            if (dumpAll) {
2659                r.dump(pw, innerPrefix);
2660            }
2661        }
2662        if (r.app != null && r.app.thread != null) {
2663            pw.print(prefix); pw.println("  Client:");
2664            pw.flush();
2665            try {
2666                TransferPipe tp = new TransferPipe();
2667                try {
2668                    r.app.thread.dumpService(tp.getWriteFd().getFileDescriptor(), r, args);
2669                    tp.setBufferPrefix(prefix + "    ");
2670                    tp.go(fd);
2671                } finally {
2672                    tp.kill();
2673                }
2674            } catch (IOException e) {
2675                pw.println(prefix + "    Failure while dumping the service: " + e);
2676            } catch (RemoteException e) {
2677                pw.println(prefix + "    Got a RemoteException while dumping the service");
2678            }
2679        }
2680    }
2681
2682}
2683