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