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