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