• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getServiceByName(ComponentName name, int callingUser)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 
getServiceByName(ComponentName name)139         ServiceRecord getServiceByName(ComponentName name) {
140             return getServiceByName(name, -1);
141         }
142 
getServiceByIntent(Intent.FilterComparison filter, int callingUser)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 
getServiceByIntent(Intent.FilterComparison filter)150         ServiceRecord getServiceByIntent(Intent.FilterComparison filter) {
151             return getServiceByIntent(filter, -1);
152         }
153 
putServiceByName(ComponentName name, int callingUser, ServiceRecord value)154         void putServiceByName(ComponentName name, int callingUser, ServiceRecord value) {
155             // TODO: Deal with global services
156             getServices(callingUser).put(name, value);
157         }
158 
putServiceByIntent(Intent.FilterComparison filter, int callingUser, ServiceRecord value)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 
removeServiceByName(ComponentName name, int callingUser)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 
removeServiceByIntent(Intent.FilterComparison filter, int callingUser)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 
getAllServices(int callingUser)181         Collection<ServiceRecord> getAllServices(int callingUser) {
182             // TODO: Deal with global services
183             return getServices(callingUser).values();
184         }
185 
getServices(int callingUser)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 
getServicesByIntent( int callingUser)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 
ActiveServices(ActivityManagerService service)207     public ActiveServices(ActivityManagerService service) {
208         mAm = service;
209     }
210 
startServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int callingPid, int callingUid, int userId)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 
stopServiceLocked(ServiceRecord service)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 
stopServiceLocked(IApplicationThread caller, Intent service, String resolvedType, int userId)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 
peekServiceLocked(Intent service, String resolvedType)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 
stopServiceTokenLocked(ComponentName className, IBinder token, int startId)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 
setServiceForegroundLocked(ComponentName className, IBinder token, int id, Notification notification, boolean removeNotification)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 
updateServiceForegroundLocked(ProcessRecord proc, boolean oomAdj)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 
bindServiceLocked(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, int userId)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 
publishServiceLocked(ServiceRecord r, Intent intent, IBinder service)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 
unbindServiceLocked(IServiceConnection connection)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 
unbindFinishedLocked(ServiceRecord r, Intent intent, boolean doRebind)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 
findServiceLocked(ComponentName name, IBinder token, int userId)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 
ServiceLookupResult(ServiceRecord _record, String _permission)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 
setService(ServiceRecord service)691         void setService(ServiceRecord service) {
692             mService = service;
693         }
694 
run()695         public void run() {
696             synchronized(mAm) {
697                 performServiceRestartLocked(mService);
698             }
699         }
700     }
701 
retrieveServiceLocked(Intent service, String resolvedType, int callingPid, int callingUid, int userId, boolean createIfNeeded)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 
bumpServiceExecutingLocked(ServiceRecord r, String why)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 
requestServiceBindingLocked(ServiceRecord r, IntentBindRecord i, boolean rebind)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 
scheduleServiceRestartLocked(ServiceRecord r, boolean allowCancel)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 
performServiceRestartLocked(ServiceRecord r)951     final void performServiceRestartLocked(ServiceRecord r) {
952         if (!mRestartingServices.contains(r)) {
953             return;
954         }
955         bringUpServiceLocked(r, r.intent.getIntent().getFlags(), true);
956     }
957 
unscheduleServiceRestartLocked(ServiceRecord r)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 
bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean whileRestarting)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 
requestServiceBindingsLocked(ServiceRecord r)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 
realStartServiceLocked(ServiceRecord r, ProcessRecord app)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 
sendServiceArgsLocked(ServiceRecord r, boolean oomAdjusted)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 
bringDownServiceLocked(ServiceRecord r, boolean force)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 
removeConnectionLocked( ConnectionRecord c, ProcessRecord skipApp, ActivityRecord skipAct)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 
serviceDoneExecutingLocked(ServiceRecord r, int type, int startId, int res)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 
serviceDoneExecutingLocked(ServiceRecord r, boolean inStopping)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 
attachApplicationLocked(ProcessRecord proc, String processName)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 
processStartTimedOutLocked(ProcessRecord proc)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 
collectForceStopServicesLocked(String name, int userId, boolean evenPersistent, boolean doit, HashMap<ComponentName, ServiceRecord> services, ArrayList<ServiceRecord> result)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 
forceStopLocked(String name, int userId, boolean evenPersistent, boolean doit)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 
cleanUpRemovedTaskLocked(TaskRecord tr, ComponentName component, Intent baseIntent)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 
killServicesLocked(ProcessRecord app, boolean allowRestart)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 
makeRunningServiceInfoLocked(ServiceRecord r)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 
getRunningServiceInfoLocked(int maxNum, int flags)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 
getRunningServiceControlPanelLocked(ComponentName name)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 
serviceTimeout(ProcessRecord proc)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      */
dumpServicesLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, boolean dumpClient, String dumpPackage)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      */
dumpService(FileDescriptor fd, PrintWriter pw, String name, String[] args, int opti, boolean dumpAll)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      */
dumpService(String prefix, FileDescriptor fd, PrintWriter pw, final ServiceRecord r, String[] args, boolean dumpAll)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