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