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