1 /* 2 * Copyright (C) 2006 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 com.android.internal.app.procstats.ServiceState; 20 import com.android.internal.os.BatteryStatsImpl; 21 import com.android.server.LocalServices; 22 import com.android.server.notification.NotificationManagerInternal; 23 24 import android.app.INotificationManager; 25 import android.app.Notification; 26 import android.app.NotificationManager; 27 import android.app.PendingIntent; 28 import android.content.ComponentName; 29 import android.content.Context; 30 import android.content.Intent; 31 import android.content.pm.ApplicationInfo; 32 import android.content.pm.PackageManager; 33 import android.content.pm.ServiceInfo; 34 import android.net.Uri; 35 import android.os.Binder; 36 import android.os.IBinder; 37 import android.os.RemoteException; 38 import android.os.SystemClock; 39 import android.os.UserHandle; 40 import android.provider.Settings; 41 import android.util.ArrayMap; 42 import android.util.Slog; 43 import android.util.TimeUtils; 44 45 import java.io.PrintWriter; 46 import java.util.ArrayList; 47 import java.util.List; 48 import java.util.Objects; 49 50 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 51 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 52 53 /** 54 * A running application service. 55 */ 56 final class ServiceRecord extends Binder { 57 private static final String TAG = TAG_WITH_CLASS_NAME ? "ServiceRecord" : TAG_AM; 58 59 // Maximum number of delivery attempts before giving up. 60 static final int MAX_DELIVERY_COUNT = 3; 61 62 // Maximum number of times it can fail during execution before giving up. 63 static final int MAX_DONE_EXECUTING_COUNT = 6; 64 65 final ActivityManagerService ams; 66 final BatteryStatsImpl.Uid.Pkg.Serv stats; 67 final ComponentName name; // service component. 68 final String shortName; // name.flattenToShortString(). 69 final Intent.FilterComparison intent; 70 // original intent used to find service. 71 final ServiceInfo serviceInfo; 72 // all information about the service. 73 final ApplicationInfo appInfo; 74 // information about service's app. 75 final int userId; // user that this service is running as 76 final String packageName; // the package implementing intent's component 77 final String processName; // process where this component wants to run 78 final String permission;// permission needed to access service 79 final boolean exported; // from ServiceInfo.exported 80 final Runnable restarter; // used to schedule retries of starting the service 81 final long createTime; // when this service was created 82 final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings 83 = new ArrayMap<Intent.FilterComparison, IntentBindRecord>(); 84 // All active bindings to the service. 85 final ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections 86 = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>(); 87 // IBinder -> ConnectionRecord of all bound clients 88 89 ProcessRecord app; // where this service is running or null. 90 ProcessRecord isolatedProc; // keep track of isolated process, if requested 91 ServiceState tracker; // tracking service execution, may be null 92 ServiceState restartTracker; // tracking service restart 93 boolean whitelistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT? 94 boolean delayed; // are we waiting to start this service in the background? 95 boolean isForeground; // is service currently in foreground mode? 96 int foregroundId; // Notification ID of last foreground req. 97 Notification foregroundNoti; // Notification record of foreground state. 98 long lastActivity; // last time there was some activity on the service. 99 long startingBgTimeout; // time at which we scheduled this for a delayed start. 100 boolean startRequested; // someone explicitly called start? 101 boolean delayedStop; // service has been stopped but is in a delayed start? 102 boolean stopIfKilled; // last onStart() said to stop if service killed? 103 boolean callStart; // last onStart() has asked to alway be called on restart. 104 int executeNesting; // number of outstanding operations keeping foreground. 105 boolean executeFg; // should we be executing in the foreground? 106 long executingStart; // start time of last execute request. 107 boolean createdFromFg; // was this service last created due to a foreground process call? 108 int crashCount; // number of times proc has crashed with service running 109 int totalRestartCount; // number of times we have had to restart. 110 int restartCount; // number of restarts performed in a row. 111 long restartDelay; // delay until next restart attempt. 112 long restartTime; // time of last restart. 113 long nextRestartTime; // time when restartDelay will expire. 114 boolean destroying; // set when we have started destroying the service 115 long destroyTime; // time at which destory was initiated. 116 117 String stringName; // caching of toString 118 119 private int lastStartId; // identifier of most recent start request. 120 121 static class StartItem { 122 final ServiceRecord sr; 123 final boolean taskRemoved; 124 final int id; 125 final Intent intent; 126 final ActivityManagerService.NeededUriGrants neededGrants; 127 long deliveredTime; 128 int deliveryCount; 129 int doneExecutingCount; 130 UriPermissionOwner uriPermissions; 131 132 String stringName; // caching of toString 133 StartItem(ServiceRecord _sr, boolean _taskRemoved, int _id, Intent _intent, ActivityManagerService.NeededUriGrants _neededGrants)134 StartItem(ServiceRecord _sr, boolean _taskRemoved, int _id, Intent _intent, 135 ActivityManagerService.NeededUriGrants _neededGrants) { 136 sr = _sr; 137 taskRemoved = _taskRemoved; 138 id = _id; 139 intent = _intent; 140 neededGrants = _neededGrants; 141 } 142 getUriPermissionsLocked()143 UriPermissionOwner getUriPermissionsLocked() { 144 if (uriPermissions == null) { 145 uriPermissions = new UriPermissionOwner(sr.ams, this); 146 } 147 return uriPermissions; 148 } 149 removeUriPermissionsLocked()150 void removeUriPermissionsLocked() { 151 if (uriPermissions != null) { 152 uriPermissions.removeUriPermissionsLocked(); 153 uriPermissions = null; 154 } 155 } 156 toString()157 public String toString() { 158 if (stringName != null) { 159 return stringName; 160 } 161 StringBuilder sb = new StringBuilder(128); 162 sb.append("ServiceRecord{") 163 .append(Integer.toHexString(System.identityHashCode(sr))) 164 .append(' ').append(sr.shortName) 165 .append(" StartItem ") 166 .append(Integer.toHexString(System.identityHashCode(this))) 167 .append(" id=").append(id).append('}'); 168 return stringName = sb.toString(); 169 } 170 } 171 172 final ArrayList<StartItem> deliveredStarts = new ArrayList<StartItem>(); 173 // start() arguments which been delivered. 174 final ArrayList<StartItem> pendingStarts = new ArrayList<StartItem>(); 175 // start() arguments that haven't yet been delivered. 176 dumpStartList(PrintWriter pw, String prefix, List<StartItem> list, long now)177 void dumpStartList(PrintWriter pw, String prefix, List<StartItem> list, long now) { 178 final int N = list.size(); 179 for (int i=0; i<N; i++) { 180 StartItem si = list.get(i); 181 pw.print(prefix); pw.print("#"); pw.print(i); 182 pw.print(" id="); pw.print(si.id); 183 if (now != 0) { 184 pw.print(" dur="); 185 TimeUtils.formatDuration(si.deliveredTime, now, pw); 186 } 187 if (si.deliveryCount != 0) { 188 pw.print(" dc="); pw.print(si.deliveryCount); 189 } 190 if (si.doneExecutingCount != 0) { 191 pw.print(" dxc="); pw.print(si.doneExecutingCount); 192 } 193 pw.println(""); 194 pw.print(prefix); pw.print(" intent="); 195 if (si.intent != null) pw.println(si.intent.toString()); 196 else pw.println("null"); 197 if (si.neededGrants != null) { 198 pw.print(prefix); pw.print(" neededGrants="); 199 pw.println(si.neededGrants); 200 } 201 if (si.uriPermissions != null) { 202 si.uriPermissions.dump(pw, prefix); 203 } 204 } 205 } 206 dump(PrintWriter pw, String prefix)207 void dump(PrintWriter pw, String prefix) { 208 pw.print(prefix); pw.print("intent={"); 209 pw.print(intent.getIntent().toShortString(false, true, false, true)); 210 pw.println('}'); 211 pw.print(prefix); pw.print("packageName="); pw.println(packageName); 212 pw.print(prefix); pw.print("processName="); pw.println(processName); 213 if (permission != null) { 214 pw.print(prefix); pw.print("permission="); pw.println(permission); 215 } 216 long now = SystemClock.uptimeMillis(); 217 long nowReal = SystemClock.elapsedRealtime(); 218 if (appInfo != null) { 219 pw.print(prefix); pw.print("baseDir="); pw.println(appInfo.sourceDir); 220 if (!Objects.equals(appInfo.sourceDir, appInfo.publicSourceDir)) { 221 pw.print(prefix); pw.print("resDir="); pw.println(appInfo.publicSourceDir); 222 } 223 pw.print(prefix); pw.print("dataDir="); pw.println(appInfo.dataDir); 224 } 225 pw.print(prefix); pw.print("app="); pw.println(app); 226 if (isolatedProc != null) { 227 pw.print(prefix); pw.print("isolatedProc="); pw.println(isolatedProc); 228 } 229 if (whitelistManager) { 230 pw.print(prefix); pw.print("whitelistManager="); pw.println(whitelistManager); 231 } 232 if (delayed) { 233 pw.print(prefix); pw.print("delayed="); pw.println(delayed); 234 } 235 if (isForeground || foregroundId != 0) { 236 pw.print(prefix); pw.print("isForeground="); pw.print(isForeground); 237 pw.print(" foregroundId="); pw.print(foregroundId); 238 pw.print(" foregroundNoti="); pw.println(foregroundNoti); 239 } 240 pw.print(prefix); pw.print("createTime="); 241 TimeUtils.formatDuration(createTime, nowReal, pw); 242 pw.print(" startingBgTimeout="); 243 TimeUtils.formatDuration(startingBgTimeout, now, pw); 244 pw.println(); 245 pw.print(prefix); pw.print("lastActivity="); 246 TimeUtils.formatDuration(lastActivity, now, pw); 247 pw.print(" restartTime="); 248 TimeUtils.formatDuration(restartTime, now, pw); 249 pw.print(" createdFromFg="); pw.println(createdFromFg); 250 if (startRequested || delayedStop || lastStartId != 0) { 251 pw.print(prefix); pw.print("startRequested="); pw.print(startRequested); 252 pw.print(" delayedStop="); pw.print(delayedStop); 253 pw.print(" stopIfKilled="); pw.print(stopIfKilled); 254 pw.print(" callStart="); pw.print(callStart); 255 pw.print(" lastStartId="); pw.println(lastStartId); 256 } 257 if (executeNesting != 0) { 258 pw.print(prefix); pw.print("executeNesting="); pw.print(executeNesting); 259 pw.print(" executeFg="); pw.print(executeFg); 260 pw.print(" executingStart="); 261 TimeUtils.formatDuration(executingStart, now, pw); 262 pw.println(); 263 } 264 if (destroying || destroyTime != 0) { 265 pw.print(prefix); pw.print("destroying="); pw.print(destroying); 266 pw.print(" destroyTime="); 267 TimeUtils.formatDuration(destroyTime, now, pw); 268 pw.println(); 269 } 270 if (crashCount != 0 || restartCount != 0 271 || restartDelay != 0 || nextRestartTime != 0) { 272 pw.print(prefix); pw.print("restartCount="); pw.print(restartCount); 273 pw.print(" restartDelay="); 274 TimeUtils.formatDuration(restartDelay, now, pw); 275 pw.print(" nextRestartTime="); 276 TimeUtils.formatDuration(nextRestartTime, now, pw); 277 pw.print(" crashCount="); pw.println(crashCount); 278 } 279 if (deliveredStarts.size() > 0) { 280 pw.print(prefix); pw.println("Delivered Starts:"); 281 dumpStartList(pw, prefix, deliveredStarts, now); 282 } 283 if (pendingStarts.size() > 0) { 284 pw.print(prefix); pw.println("Pending Starts:"); 285 dumpStartList(pw, prefix, pendingStarts, 0); 286 } 287 if (bindings.size() > 0) { 288 pw.print(prefix); pw.println("Bindings:"); 289 for (int i=0; i<bindings.size(); i++) { 290 IntentBindRecord b = bindings.valueAt(i); 291 pw.print(prefix); pw.print("* IntentBindRecord{"); 292 pw.print(Integer.toHexString(System.identityHashCode(b))); 293 if ((b.collectFlags()&Context.BIND_AUTO_CREATE) != 0) { 294 pw.append(" CREATE"); 295 } 296 pw.println("}:"); 297 b.dumpInService(pw, prefix + " "); 298 } 299 } 300 if (connections.size() > 0) { 301 pw.print(prefix); pw.println("All Connections:"); 302 for (int conni=0; conni<connections.size(); conni++) { 303 ArrayList<ConnectionRecord> c = connections.valueAt(conni); 304 for (int i=0; i<c.size(); i++) { 305 pw.print(prefix); pw.print(" "); pw.println(c.get(i)); 306 } 307 } 308 } 309 } 310 ServiceRecord(ActivityManagerService ams, BatteryStatsImpl.Uid.Pkg.Serv servStats, ComponentName name, Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg, Runnable restarter)311 ServiceRecord(ActivityManagerService ams, 312 BatteryStatsImpl.Uid.Pkg.Serv servStats, ComponentName name, 313 Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg, 314 Runnable restarter) { 315 this.ams = ams; 316 this.stats = servStats; 317 this.name = name; 318 shortName = name.flattenToShortString(); 319 this.intent = intent; 320 serviceInfo = sInfo; 321 appInfo = sInfo.applicationInfo; 322 packageName = sInfo.applicationInfo.packageName; 323 processName = sInfo.processName; 324 permission = sInfo.permission; 325 exported = sInfo.exported; 326 this.restarter = restarter; 327 createTime = SystemClock.elapsedRealtime(); 328 lastActivity = SystemClock.uptimeMillis(); 329 userId = UserHandle.getUserId(appInfo.uid); 330 createdFromFg = callerIsFg; 331 } 332 getTracker()333 public ServiceState getTracker() { 334 if (tracker != null) { 335 return tracker; 336 } 337 if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) { 338 tracker = ams.mProcessStats.getServiceStateLocked(serviceInfo.packageName, 339 serviceInfo.applicationInfo.uid, serviceInfo.applicationInfo.versionCode, 340 serviceInfo.processName, serviceInfo.name); 341 tracker.applyNewOwner(this); 342 } 343 return tracker; 344 } 345 forceClearTracker()346 public void forceClearTracker() { 347 if (tracker != null) { 348 tracker.clearCurrentOwner(this, true); 349 tracker = null; 350 } 351 } 352 makeRestarting(int memFactor, long now)353 public void makeRestarting(int memFactor, long now) { 354 if (restartTracker == null) { 355 if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) { 356 restartTracker = ams.mProcessStats.getServiceStateLocked(serviceInfo.packageName, 357 serviceInfo.applicationInfo.uid, serviceInfo.applicationInfo.versionCode, 358 serviceInfo.processName, serviceInfo.name); 359 } 360 if (restartTracker == null) { 361 return; 362 } 363 } 364 restartTracker.setRestarting(true, memFactor, now); 365 } 366 retrieveAppBindingLocked(Intent intent, ProcessRecord app)367 public AppBindRecord retrieveAppBindingLocked(Intent intent, 368 ProcessRecord app) { 369 Intent.FilterComparison filter = new Intent.FilterComparison(intent); 370 IntentBindRecord i = bindings.get(filter); 371 if (i == null) { 372 i = new IntentBindRecord(this, filter); 373 bindings.put(filter, i); 374 } 375 AppBindRecord a = i.apps.get(app); 376 if (a != null) { 377 return a; 378 } 379 a = new AppBindRecord(this, i, app); 380 i.apps.put(app, a); 381 return a; 382 } 383 hasAutoCreateConnections()384 public boolean hasAutoCreateConnections() { 385 // XXX should probably keep a count of the number of auto-create 386 // connections directly in the service. 387 for (int conni=connections.size()-1; conni>=0; conni--) { 388 ArrayList<ConnectionRecord> cr = connections.valueAt(conni); 389 for (int i=0; i<cr.size(); i++) { 390 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) { 391 return true; 392 } 393 } 394 } 395 return false; 396 } 397 updateWhitelistManager()398 public void updateWhitelistManager() { 399 whitelistManager = false; 400 for (int conni=connections.size()-1; conni>=0; conni--) { 401 ArrayList<ConnectionRecord> cr = connections.valueAt(conni); 402 for (int i=0; i<cr.size(); i++) { 403 if ((cr.get(i).flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) { 404 whitelistManager = true; 405 return; 406 } 407 } 408 } 409 } 410 resetRestartCounter()411 public void resetRestartCounter() { 412 restartCount = 0; 413 restartDelay = 0; 414 restartTime = 0; 415 } 416 findDeliveredStart(int id, boolean remove)417 public StartItem findDeliveredStart(int id, boolean remove) { 418 final int N = deliveredStarts.size(); 419 for (int i=0; i<N; i++) { 420 StartItem si = deliveredStarts.get(i); 421 if (si.id == id) { 422 if (remove) deliveredStarts.remove(i); 423 return si; 424 } 425 } 426 427 return null; 428 } 429 getLastStartId()430 public int getLastStartId() { 431 return lastStartId; 432 } 433 makeNextStartId()434 public int makeNextStartId() { 435 lastStartId++; 436 if (lastStartId < 1) { 437 lastStartId = 1; 438 } 439 return lastStartId; 440 } 441 postNotification()442 public void postNotification() { 443 final int appUid = appInfo.uid; 444 final int appPid = app.pid; 445 if (foregroundId != 0 && foregroundNoti != null) { 446 // Do asynchronous communication with notification manager to 447 // avoid deadlocks. 448 final String localPackageName = packageName; 449 final int localForegroundId = foregroundId; 450 final Notification _foregroundNoti = foregroundNoti; 451 ams.mHandler.post(new Runnable() { 452 public void run() { 453 NotificationManagerInternal nm = LocalServices.getService( 454 NotificationManagerInternal.class); 455 if (nm == null) { 456 return; 457 } 458 Notification localForegroundNoti = _foregroundNoti; 459 try { 460 if (localForegroundNoti.getSmallIcon() == null) { 461 // It is not correct for the caller to not supply a notification 462 // icon, but this used to be able to slip through, so for 463 // those dirty apps we will create a notification clearly 464 // blaming the app. 465 Slog.v(TAG, "Attempted to start a foreground service (" 466 + name 467 + ") with a broken notification (no icon: " 468 + localForegroundNoti 469 + ")"); 470 471 CharSequence appName = appInfo.loadLabel( 472 ams.mContext.getPackageManager()); 473 if (appName == null) { 474 appName = appInfo.packageName; 475 } 476 Context ctx = null; 477 try { 478 ctx = ams.mContext.createPackageContextAsUser( 479 appInfo.packageName, 0, new UserHandle(userId)); 480 481 Notification.Builder notiBuilder = new Notification.Builder(ctx); 482 483 // it's ugly, but it clearly identifies the app 484 notiBuilder.setSmallIcon(appInfo.icon); 485 486 // mark as foreground 487 notiBuilder.setFlag(Notification.FLAG_FOREGROUND_SERVICE, true); 488 489 // we are doing the app a kindness here 490 notiBuilder.setPriority(Notification.PRIORITY_MIN); 491 492 Intent runningIntent = new Intent( 493 Settings.ACTION_APPLICATION_DETAILS_SETTINGS); 494 runningIntent.setData(Uri.fromParts("package", 495 appInfo.packageName, null)); 496 PendingIntent pi = PendingIntent.getActivity(ams.mContext, 0, 497 runningIntent, PendingIntent.FLAG_UPDATE_CURRENT); 498 notiBuilder.setColor(ams.mContext.getColor( 499 com.android.internal 500 .R.color.system_notification_accent_color)); 501 notiBuilder.setContentTitle( 502 ams.mContext.getString( 503 com.android.internal.R.string 504 .app_running_notification_title, 505 appName)); 506 notiBuilder.setContentText( 507 ams.mContext.getString( 508 com.android.internal.R.string 509 .app_running_notification_text, 510 appName)); 511 notiBuilder.setContentIntent(pi); 512 513 localForegroundNoti = notiBuilder.build(); 514 } catch (PackageManager.NameNotFoundException e) { 515 } 516 } 517 if (localForegroundNoti.getSmallIcon() == null) { 518 // Notifications whose icon is 0 are defined to not show 519 // a notification, silently ignoring it. We don't want to 520 // just ignore it, we want to prevent the service from 521 // being foreground. 522 throw new RuntimeException("invalid service notification: " 523 + foregroundNoti); 524 } 525 int[] outId = new int[1]; 526 nm.enqueueNotification(localPackageName, localPackageName, 527 appUid, appPid, null, localForegroundId, localForegroundNoti, 528 outId, userId); 529 530 foregroundNoti = localForegroundNoti; // save it for amending next time 531 } catch (RuntimeException e) { 532 Slog.w(TAG, "Error showing notification for service", e); 533 // If it gave us a garbage notification, it doesn't 534 // get to be foreground. 535 ams.setServiceForeground(name, ServiceRecord.this, 536 0, null, 0); 537 ams.crashApplication(appUid, appPid, localPackageName, 538 "Bad notification for startForeground: " + e); 539 } 540 } 541 }); 542 } 543 } 544 cancelNotification()545 public void cancelNotification() { 546 if (foregroundId != 0) { 547 // Do asynchronous communication with notification manager to 548 // avoid deadlocks. 549 final String localPackageName = packageName; 550 final int localForegroundId = foregroundId; 551 ams.mHandler.post(new Runnable() { 552 public void run() { 553 INotificationManager inm = NotificationManager.getService(); 554 if (inm == null) { 555 return; 556 } 557 try { 558 inm.cancelNotificationWithTag(localPackageName, null, 559 localForegroundId, userId); 560 } catch (RuntimeException e) { 561 Slog.w(TAG, "Error canceling notification for service", e); 562 } catch (RemoteException e) { 563 } 564 } 565 }); 566 } 567 } 568 stripForegroundServiceFlagFromNotification()569 public void stripForegroundServiceFlagFromNotification() { 570 if (foregroundId == 0) { 571 return; 572 } 573 574 final int localForegroundId = foregroundId; 575 final int localUserId = userId; 576 final String localPackageName = packageName; 577 578 // Do asynchronous communication with notification manager to 579 // avoid deadlocks. 580 ams.mHandler.post(new Runnable() { 581 @Override 582 public void run() { 583 NotificationManagerInternal nmi = LocalServices.getService( 584 NotificationManagerInternal.class); 585 if (nmi == null) { 586 return; 587 } 588 nmi.removeForegroundServiceFlagFromNotification(localPackageName, localForegroundId, 589 localUserId); 590 } 591 }); 592 } 593 clearDeliveredStartsLocked()594 public void clearDeliveredStartsLocked() { 595 for (int i=deliveredStarts.size()-1; i>=0; i--) { 596 deliveredStarts.get(i).removeUriPermissionsLocked(); 597 } 598 deliveredStarts.clear(); 599 } 600 toString()601 public String toString() { 602 if (stringName != null) { 603 return stringName; 604 } 605 StringBuilder sb = new StringBuilder(128); 606 sb.append("ServiceRecord{") 607 .append(Integer.toHexString(System.identityHashCode(this))) 608 .append(" u").append(userId) 609 .append(' ').append(shortName).append('}'); 610 return stringName = sb.toString(); 611 } 612 } 613