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 StartItem(ServiceRecord _sr, boolean _taskRemoved, int _id, Intent _intent, ActivityManagerService.NeededUriGrants _neededGrants, int _callingId)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 getUriPermissionsLocked()150 UriPermissionOwner getUriPermissionsLocked() { 151 if (uriPermissions == null) { 152 uriPermissions = new UriPermissionOwner(sr.ams, this); 153 } 154 return uriPermissions; 155 } 156 removeUriPermissionsLocked()157 void removeUriPermissionsLocked() { 158 if (uriPermissions != null) { 159 uriPermissions.removeUriPermissionsLocked(); 160 uriPermissions = null; 161 } 162 } 163 writeToProto(ProtoOutputStream proto, long fieldId, long now)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 toString()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 dumpStartList(PrintWriter pw, String prefix, List<StartItem> list, long now)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 writeToProto(ProtoOutputStream proto, long fieldId)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 dump(PrintWriter pw, String prefix)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 ServiceRecord(ActivityManagerService ams, BatteryStatsImpl.Uid.Pkg.Serv servStats, ComponentName name, Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg, Runnable restarter)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 getTracker()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 forceClearTracker()482 public void forceClearTracker() { 483 if (tracker != null) { 484 tracker.clearCurrentOwner(this, true); 485 tracker = null; 486 } 487 } 488 makeRestarting(int memFactor, long now)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 retrieveAppBindingLocked(Intent intent, ProcessRecord app)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 hasAutoCreateConnections()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 updateWhitelistManager()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 resetRestartCounter()547 public void resetRestartCounter() { 548 restartCount = 0; 549 restartDelay = 0; 550 restartTime = 0; 551 } 552 findDeliveredStart(int id, boolean taskRemoved, boolean remove)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 getLastStartId()566 public int getLastStartId() { 567 return lastStartId; 568 } 569 makeNextStartId()570 public int makeNextStartId() { 571 lastStartId++; 572 if (lastStartId < 1) { 573 lastStartId = 1; 574 } 575 return lastStartId; 576 } 577 postNotification()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 cancelNotification()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 stripForegroundServiceFlagFromNotification()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 clearDeliveredStartsLocked()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 toString()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 getComponentName()761 public ComponentName getComponentName() { 762 return name; 763 } 764 } 765