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