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