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 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 143 UriPermissionOwner getUriPermissionsLocked() { 144 if (uriPermissions == null) { 145 uriPermissions = new UriPermissionOwner(sr.ams, this); 146 } 147 return uriPermissions; 148 } 149 150 void removeUriPermissionsLocked() { 151 if (uriPermissions != null) { 152 uriPermissions.removeUriPermissionsLocked(); 153 uriPermissions = null; 154 } 155 } 156 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 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 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 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 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 346 public void forceClearTracker() { 347 if (tracker != null) { 348 tracker.clearCurrentOwner(this, true); 349 tracker = null; 350 } 351 } 352 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 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 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 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 411 public void resetRestartCounter() { 412 restartCount = 0; 413 restartDelay = 0; 414 restartTime = 0; 415 } 416 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 430 public int getLastStartId() { 431 return lastStartId; 432 } 433 434 public int makeNextStartId() { 435 lastStartId++; 436 if (lastStartId < 1) { 437 lastStartId = 1; 438 } 439 return lastStartId; 440 } 441 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 545 public void cancelNotification() { 546 // Do asynchronous communication with notification manager to 547 // avoid deadlocks. 548 final String localPackageName = packageName; 549 final int localForegroundId = foregroundId; 550 ams.mHandler.post(new Runnable() { 551 public void run() { 552 INotificationManager inm = NotificationManager.getService(); 553 if (inm == null) { 554 return; 555 } 556 try { 557 inm.cancelNotificationWithTag(localPackageName, null, 558 localForegroundId, userId); 559 } catch (RuntimeException e) { 560 Slog.w(TAG, "Error canceling notification for service", e); 561 } catch (RemoteException e) { 562 } 563 } 564 }); 565 } 566 567 public void stripForegroundServiceFlagFromNotification() { 568 if (foregroundId == 0) { 569 return; 570 } 571 572 final int localForegroundId = foregroundId; 573 final int localUserId = userId; 574 final String localPackageName = packageName; 575 576 // Do asynchronous communication with notification manager to 577 // avoid deadlocks. 578 ams.mHandler.post(new Runnable() { 579 @Override 580 public void run() { 581 NotificationManagerInternal nmi = LocalServices.getService( 582 NotificationManagerInternal.class); 583 if (nmi == null) { 584 return; 585 } 586 nmi.removeForegroundServiceFlagFromNotification(localPackageName, localForegroundId, 587 localUserId); 588 } 589 }); 590 } 591 592 public void clearDeliveredStartsLocked() { 593 for (int i=deliveredStarts.size()-1; i>=0; i--) { 594 deliveredStarts.get(i).removeUriPermissionsLocked(); 595 } 596 deliveredStarts.clear(); 597 } 598 599 public String toString() { 600 if (stringName != null) { 601 return stringName; 602 } 603 StringBuilder sb = new StringBuilder(128); 604 sb.append("ServiceRecord{") 605 .append(Integer.toHexString(System.identityHashCode(this))) 606 .append(" u").append(userId) 607 .append(' ').append(shortName).append('}'); 608 return stringName = sb.toString(); 609 } 610 } 611