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 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 147 UriPermissionOwner getUriPermissionsLocked() { 148 if (uriPermissions == null) { 149 uriPermissions = new UriPermissionOwner(sr.ams, this); 150 } 151 return uriPermissions; 152 } 153 154 void removeUriPermissionsLocked() { 155 if (uriPermissions != null) { 156 uriPermissions.removeUriPermissionsLocked(); 157 uriPermissions = null; 158 } 159 } 160 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 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 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 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 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 350 public void forceClearTracker() { 351 if (tracker != null) { 352 tracker.clearCurrentOwner(this, true); 353 tracker = null; 354 } 355 } 356 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 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 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 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 415 public void resetRestartCounter() { 416 restartCount = 0; 417 restartDelay = 0; 418 restartTime = 0; 419 } 420 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 434 public int getLastStartId() { 435 return lastStartId; 436 } 437 438 public int makeNextStartId() { 439 lastStartId++; 440 if (lastStartId < 1) { 441 lastStartId = 1; 442 } 443 return lastStartId; 444 } 445 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 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 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 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 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