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 static android.app.PendingIntent.FLAG_IMMUTABLE; 20 import static android.app.PendingIntent.FLAG_UPDATE_CURRENT; 21 import static android.os.PowerExemptionManager.REASON_DENIED; 22 23 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOREGROUND_SERVICE; 24 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 25 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 26 27 import android.annotation.Nullable; 28 import android.app.IApplicationThread; 29 import android.app.Notification; 30 import android.app.PendingIntent; 31 import android.app.RemoteServiceException.CannotPostForegroundServiceNotificationException; 32 import android.content.ComponentName; 33 import android.content.Context; 34 import android.content.Intent; 35 import android.content.pm.ApplicationInfo; 36 import android.content.pm.PackageManager; 37 import android.content.pm.ServiceInfo; 38 import android.net.Uri; 39 import android.os.Binder; 40 import android.os.Build; 41 import android.os.IBinder; 42 import android.os.PowerExemptionManager; 43 import android.os.SystemClock; 44 import android.os.UserHandle; 45 import android.provider.Settings; 46 import android.util.ArrayMap; 47 import android.util.Slog; 48 import android.util.TimeUtils; 49 import android.util.proto.ProtoOutputStream; 50 import android.util.proto.ProtoUtils; 51 52 import com.android.internal.annotations.GuardedBy; 53 import com.android.internal.app.procstats.ServiceState; 54 import com.android.server.LocalServices; 55 import com.android.server.notification.NotificationManagerInternal; 56 import com.android.server.uri.NeededUriGrants; 57 import com.android.server.uri.UriPermissionOwner; 58 59 import java.io.PrintWriter; 60 import java.util.ArrayList; 61 import java.util.List; 62 import java.util.Objects; 63 64 /** 65 * A running application service. 66 */ 67 final class ServiceRecord extends Binder implements ComponentName.WithComponentName { 68 private static final String TAG = TAG_WITH_CLASS_NAME ? "ServiceRecord" : TAG_AM; 69 70 // Maximum number of delivery attempts before giving up. 71 static final int MAX_DELIVERY_COUNT = 3; 72 73 // Maximum number of times it can fail during execution before giving up. 74 static final int MAX_DONE_EXECUTING_COUNT = 6; 75 76 final ActivityManagerService ams; 77 final ComponentName name; // service component. 78 final ComponentName instanceName; // service component's per-instance name. 79 final String shortInstanceName; // instanceName.flattenToShortString(). 80 final String definingPackageName; 81 // Can be different from appInfo.packageName for external services 82 final int definingUid; 83 // Can be different from appInfo.uid for external services 84 final Intent.FilterComparison intent; 85 // original intent used to find service. 86 final ServiceInfo serviceInfo; 87 // all information about the service. 88 ApplicationInfo appInfo; 89 // information about service's app. 90 final int userId; // user that this service is running as 91 final String packageName; // the package implementing intent's component 92 final String processName; // process where this component wants to run 93 final String permission;// permission needed to access service 94 final boolean exported; // from ServiceInfo.exported 95 final Runnable restarter; // used to schedule retries of starting the service 96 final long createRealTime; // when this service was created 97 final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings 98 = new ArrayMap<Intent.FilterComparison, IntentBindRecord>(); 99 // All active bindings to the service. 100 private final ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections 101 = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>(); 102 // IBinder -> ConnectionRecord of all bound clients 103 104 ProcessRecord app; // where this service is running or null. 105 ProcessRecord isolatedProc; // keep track of isolated process, if requested 106 ServiceState tracker; // tracking service execution, may be null 107 ServiceState restartTracker; // tracking service restart 108 boolean allowlistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT? 109 boolean delayed; // are we waiting to start this service in the background? 110 boolean fgRequired; // is the service required to go foreground after starting? 111 boolean fgWaiting; // is a timeout for going foreground already scheduled? 112 boolean isNotAppComponentUsage; // is service binding not considered component/package usage? 113 boolean isForeground; // is service currently in foreground mode? 114 int foregroundId; // Notification ID of last foreground req. 115 Notification foregroundNoti; // Notification record of foreground state. 116 long fgDisplayTime; // time at which the FGS notification should become visible 117 int foregroundServiceType; // foreground service types. 118 long lastActivity; // last time there was some activity on the service. 119 long startingBgTimeout; // time at which we scheduled this for a delayed start. 120 boolean startRequested; // someone explicitly called start? 121 boolean delayedStop; // service has been stopped but is in a delayed start? 122 boolean stopIfKilled; // last onStart() said to stop if service killed? 123 boolean callStart; // last onStart() has asked to always be called on restart. 124 int executeNesting; // number of outstanding operations keeping foreground. 125 boolean executeFg; // should we be executing in the foreground? 126 long executingStart; // start time of last execute request. 127 boolean createdFromFg; // was this service last created due to a foreground process call? 128 int crashCount; // number of times proc has crashed with service running 129 int totalRestartCount; // number of times we have had to restart. 130 int restartCount; // number of restarts performed in a row. 131 long restartDelay; // delay until next restart attempt. 132 long restartTime; // time of last restart. 133 long nextRestartTime; // time when restartDelay will expire. 134 boolean destroying; // set when we have started destroying the service 135 long destroyTime; // time at which destory was initiated. 136 int pendingConnectionGroup; // To be filled in to ProcessRecord once it connects 137 int pendingConnectionImportance; // To be filled in to ProcessRecord once it connects 138 139 // any current binding to this service has BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS flag? 140 private boolean mIsAllowedBgActivityStartsByBinding; 141 // is this service currently allowed to start activities from background by providing 142 // allowBackgroundActivityStarts=true to startServiceLocked()? 143 private boolean mIsAllowedBgActivityStartsByStart; 144 // used to clean up the state of mIsAllowedBgActivityStartsByStart after a timeout 145 private Runnable mCleanUpAllowBgActivityStartsByStartCallback; 146 private ProcessRecord mAppForAllowingBgActivityStartsByStart; 147 // These are the originating tokens that currently allow bg activity starts by service start. 148 // This is used to trace back the grant when starting activities. We only pass such token to the 149 // ProcessRecord if it's the *only* cause for bg activity starts exemption, otherwise we pass 150 // null. 151 @GuardedBy("ams") 152 private List<IBinder> mBgActivityStartsByStartOriginatingTokens = new ArrayList<>(); 153 154 // allow while-in-use permissions in foreground service or not. 155 // while-in-use permissions in FGS started from background might be restricted. 156 boolean mAllowWhileInUsePermissionInFgs; 157 // A copy of mAllowWhileInUsePermissionInFgs's value when the service is entering FGS state. 158 boolean mAllowWhileInUsePermissionInFgsAtEntering; 159 160 // the most recent package that start/bind this service. 161 String mRecentCallingPackage; 162 // the most recent uid that start/bind this service. 163 int mRecentCallingUid; 164 // ApplicationInfo of the most recent callingPackage that start/bind this service. 165 @Nullable ApplicationInfo mRecentCallerApplicationInfo; 166 167 // The uptime when the service enters FGS state. 168 long mFgsEnterTime = 0; 169 // The uptime when the service exits FGS state. 170 long mFgsExitTime = 0; 171 // FGS notification is deferred. 172 boolean mFgsNotificationDeferred; 173 // FGS notification was deferred. 174 boolean mFgsNotificationWasDeferred; 175 // FGS notification was shown before the FGS finishes, or it wasn't deferred in the first place. 176 boolean mFgsNotificationShown; 177 178 // allow the service becomes foreground service? Service started from background may not be 179 // allowed to become a foreground service. 180 @PowerExemptionManager.ReasonCode int mAllowStartForeground = REASON_DENIED; 181 // A copy of mAllowStartForeground's value when the service is entering FGS state. 182 @PowerExemptionManager.ReasonCode int mAllowStartForegroundAtEntering = REASON_DENIED; 183 // Debug info why mAllowStartForeground is allowed or denied. 184 String mInfoAllowStartForeground; 185 // Debug info if mAllowStartForeground is allowed because of a temp-allowlist. 186 ActivityManagerService.FgsTempAllowListItem mInfoTempFgsAllowListReason; 187 // Is the same mInfoAllowStartForeground string has been logged before? Used for dedup. 188 boolean mLoggedInfoAllowStartForeground; 189 // The number of times Service.startForeground() is called; 190 int mStartForegroundCount; 191 // Last time mAllowWhileInUsePermissionInFgs or mAllowStartForeground is set. 192 long mLastSetFgsRestrictionTime; 193 194 String stringName; // caching of toString 195 196 private int lastStartId; // identifier of most recent start request. 197 198 boolean mKeepWarming; // Whether or not it'll keep critical code path of the host warm 199 200 static class StartItem { 201 final ServiceRecord sr; 202 final boolean taskRemoved; 203 final int id; 204 final int callingId; 205 final Intent intent; 206 final NeededUriGrants neededGrants; 207 long deliveredTime; 208 int deliveryCount; 209 int doneExecutingCount; 210 UriPermissionOwner uriPermissions; 211 212 String stringName; // caching of toString 213 StartItem(ServiceRecord _sr, boolean _taskRemoved, int _id, Intent _intent, NeededUriGrants _neededGrants, int _callingId)214 StartItem(ServiceRecord _sr, boolean _taskRemoved, int _id, Intent _intent, 215 NeededUriGrants _neededGrants, int _callingId) { 216 sr = _sr; 217 taskRemoved = _taskRemoved; 218 id = _id; 219 intent = _intent; 220 neededGrants = _neededGrants; 221 callingId = _callingId; 222 } 223 getUriPermissionsLocked()224 UriPermissionOwner getUriPermissionsLocked() { 225 if (uriPermissions == null) { 226 uriPermissions = new UriPermissionOwner(sr.ams.mUgmInternal, this); 227 } 228 return uriPermissions; 229 } 230 removeUriPermissionsLocked()231 void removeUriPermissionsLocked() { 232 if (uriPermissions != null) { 233 uriPermissions.removeUriPermissions(); 234 uriPermissions = null; 235 } 236 } 237 dumpDebug(ProtoOutputStream proto, long fieldId, long now)238 public void dumpDebug(ProtoOutputStream proto, long fieldId, long now) { 239 long token = proto.start(fieldId); 240 proto.write(ServiceRecordProto.StartItem.ID, id); 241 ProtoUtils.toDuration(proto, 242 ServiceRecordProto.StartItem.DURATION, deliveredTime, now); 243 proto.write(ServiceRecordProto.StartItem.DELIVERY_COUNT, deliveryCount); 244 proto.write(ServiceRecordProto.StartItem.DONE_EXECUTING_COUNT, doneExecutingCount); 245 if (intent != null) { 246 intent.dumpDebug(proto, ServiceRecordProto.StartItem.INTENT, true, true, 247 true, false); 248 } 249 if (neededGrants != null) { 250 neededGrants.dumpDebug(proto, ServiceRecordProto.StartItem.NEEDED_GRANTS); 251 } 252 if (uriPermissions != null) { 253 uriPermissions.dumpDebug(proto, ServiceRecordProto.StartItem.URI_PERMISSIONS); 254 } 255 proto.end(token); 256 } 257 toString()258 public String toString() { 259 if (stringName != null) { 260 return stringName; 261 } 262 StringBuilder sb = new StringBuilder(128); 263 sb.append("ServiceRecord{") 264 .append(Integer.toHexString(System.identityHashCode(sr))) 265 .append(' ').append(sr.shortInstanceName) 266 .append(" StartItem ") 267 .append(Integer.toHexString(System.identityHashCode(this))) 268 .append(" id=").append(id).append('}'); 269 return stringName = sb.toString(); 270 } 271 } 272 273 final ArrayList<StartItem> deliveredStarts = new ArrayList<StartItem>(); 274 // start() arguments which been delivered. 275 final ArrayList<StartItem> pendingStarts = new ArrayList<StartItem>(); 276 // start() arguments that haven't yet been delivered. 277 dumpStartList(PrintWriter pw, String prefix, List<StartItem> list, long now)278 void dumpStartList(PrintWriter pw, String prefix, List<StartItem> list, long now) { 279 final int N = list.size(); 280 for (int i=0; i<N; i++) { 281 StartItem si = list.get(i); 282 pw.print(prefix); pw.print("#"); pw.print(i); 283 pw.print(" id="); pw.print(si.id); 284 if (now != 0) { 285 pw.print(" dur="); 286 TimeUtils.formatDuration(si.deliveredTime, now, pw); 287 } 288 if (si.deliveryCount != 0) { 289 pw.print(" dc="); pw.print(si.deliveryCount); 290 } 291 if (si.doneExecutingCount != 0) { 292 pw.print(" dxc="); pw.print(si.doneExecutingCount); 293 } 294 pw.println(""); 295 pw.print(prefix); pw.print(" intent="); 296 if (si.intent != null) pw.println(si.intent.toString()); 297 else pw.println("null"); 298 if (si.neededGrants != null) { 299 pw.print(prefix); pw.print(" neededGrants="); 300 pw.println(si.neededGrants); 301 } 302 if (si.uriPermissions != null) { 303 si.uriPermissions.dump(pw, prefix); 304 } 305 } 306 } 307 dumpDebug(ProtoOutputStream proto, long fieldId)308 void dumpDebug(ProtoOutputStream proto, long fieldId) { 309 long token = proto.start(fieldId); 310 proto.write(ServiceRecordProto.SHORT_NAME, this.shortInstanceName); 311 proto.write(ServiceRecordProto.IS_RUNNING, app != null); 312 if (app != null) { 313 proto.write(ServiceRecordProto.PID, app.getPid()); 314 } 315 if (intent != null) { 316 intent.getIntent().dumpDebug(proto, ServiceRecordProto.INTENT, false, true, false, 317 false); 318 } 319 proto.write(ServiceRecordProto.PACKAGE_NAME, packageName); 320 proto.write(ServiceRecordProto.PROCESS_NAME, processName); 321 proto.write(ServiceRecordProto.PERMISSION, permission); 322 323 long now = SystemClock.uptimeMillis(); 324 long nowReal = SystemClock.elapsedRealtime(); 325 if (appInfo != null) { 326 long appInfoToken = proto.start(ServiceRecordProto.APPINFO); 327 proto.write(ServiceRecordProto.AppInfo.BASE_DIR, appInfo.sourceDir); 328 if (!Objects.equals(appInfo.sourceDir, appInfo.publicSourceDir)) { 329 proto.write(ServiceRecordProto.AppInfo.RES_DIR, appInfo.publicSourceDir); 330 } 331 proto.write(ServiceRecordProto.AppInfo.DATA_DIR, appInfo.dataDir); 332 proto.end(appInfoToken); 333 } 334 if (app != null) { 335 app.dumpDebug(proto, ServiceRecordProto.APP); 336 } 337 if (isolatedProc != null) { 338 isolatedProc.dumpDebug(proto, ServiceRecordProto.ISOLATED_PROC); 339 } 340 proto.write(ServiceRecordProto.WHITELIST_MANAGER, allowlistManager); 341 proto.write(ServiceRecordProto.DELAYED, delayed); 342 if (isForeground || foregroundId != 0) { 343 long fgToken = proto.start(ServiceRecordProto.FOREGROUND); 344 proto.write(ServiceRecordProto.Foreground.ID, foregroundId); 345 foregroundNoti.dumpDebug(proto, ServiceRecordProto.Foreground.NOTIFICATION); 346 proto.end(fgToken); 347 } 348 ProtoUtils.toDuration(proto, ServiceRecordProto.CREATE_REAL_TIME, createRealTime, nowReal); 349 ProtoUtils.toDuration(proto, 350 ServiceRecordProto.STARTING_BG_TIMEOUT, startingBgTimeout, now); 351 ProtoUtils.toDuration(proto, ServiceRecordProto.LAST_ACTIVITY_TIME, lastActivity, now); 352 ProtoUtils.toDuration(proto, ServiceRecordProto.RESTART_TIME, restartTime, now); 353 proto.write(ServiceRecordProto.CREATED_FROM_FG, createdFromFg); 354 proto.write(ServiceRecordProto.ALLOW_WHILE_IN_USE_PERMISSION_IN_FGS, 355 mAllowWhileInUsePermissionInFgs); 356 357 if (startRequested || delayedStop || lastStartId != 0) { 358 long startToken = proto.start(ServiceRecordProto.START); 359 proto.write(ServiceRecordProto.Start.START_REQUESTED, startRequested); 360 proto.write(ServiceRecordProto.Start.DELAYED_STOP, delayedStop); 361 proto.write(ServiceRecordProto.Start.STOP_IF_KILLED, stopIfKilled); 362 proto.write(ServiceRecordProto.Start.LAST_START_ID, lastStartId); 363 proto.end(startToken); 364 } 365 366 if (executeNesting != 0) { 367 long executNestingToken = proto.start(ServiceRecordProto.EXECUTE); 368 proto.write(ServiceRecordProto.ExecuteNesting.EXECUTE_NESTING, executeNesting); 369 proto.write(ServiceRecordProto.ExecuteNesting.EXECUTE_FG, executeFg); 370 ProtoUtils.toDuration(proto, 371 ServiceRecordProto.ExecuteNesting.EXECUTING_START, executingStart, now); 372 proto.end(executNestingToken); 373 } 374 if (destroying || destroyTime != 0) { 375 ProtoUtils.toDuration(proto, ServiceRecordProto.DESTORY_TIME, destroyTime, now); 376 } 377 if (crashCount != 0 || restartCount != 0 || restartDelay != 0 || nextRestartTime != 0) { 378 long crashToken = proto.start(ServiceRecordProto.CRASH); 379 proto.write(ServiceRecordProto.Crash.RESTART_COUNT, restartCount); 380 ProtoUtils.toDuration(proto, ServiceRecordProto.Crash.RESTART_DELAY, restartDelay, now); 381 ProtoUtils.toDuration(proto, 382 ServiceRecordProto.Crash.NEXT_RESTART_TIME, nextRestartTime, now); 383 proto.write(ServiceRecordProto.Crash.CRASH_COUNT, crashCount); 384 proto.end(crashToken); 385 } 386 387 if (deliveredStarts.size() > 0) { 388 final int N = deliveredStarts.size(); 389 for (int i = 0; i < N; i++) { 390 deliveredStarts.get(i).dumpDebug(proto, 391 ServiceRecordProto.DELIVERED_STARTS, now); 392 } 393 } 394 if (pendingStarts.size() > 0) { 395 final int N = pendingStarts.size(); 396 for (int i = 0; i < N; i++) { 397 pendingStarts.get(i).dumpDebug(proto, ServiceRecordProto.PENDING_STARTS, now); 398 } 399 } 400 if (bindings.size() > 0) { 401 final int N = bindings.size(); 402 for (int i=0; i<N; i++) { 403 IntentBindRecord b = bindings.valueAt(i); 404 b.dumpDebug(proto, ServiceRecordProto.BINDINGS); 405 } 406 } 407 if (connections.size() > 0) { 408 final int N = connections.size(); 409 for (int conni=0; conni<N; conni++) { 410 ArrayList<ConnectionRecord> c = connections.valueAt(conni); 411 for (int i=0; i<c.size(); i++) { 412 c.get(i).dumpDebug(proto, ServiceRecordProto.CONNECTIONS); 413 } 414 } 415 } 416 proto.end(token); 417 } 418 dump(PrintWriter pw, String prefix)419 void dump(PrintWriter pw, String prefix) { 420 pw.print(prefix); pw.print("intent={"); 421 pw.print(intent.getIntent().toShortString(false, true, false, false)); 422 pw.println('}'); 423 pw.print(prefix); pw.print("packageName="); pw.println(packageName); 424 pw.print(prefix); pw.print("processName="); pw.println(processName); 425 if (permission != null) { 426 pw.print(prefix); pw.print("permission="); pw.println(permission); 427 } 428 long now = SystemClock.uptimeMillis(); 429 long nowReal = SystemClock.elapsedRealtime(); 430 if (appInfo != null) { 431 pw.print(prefix); pw.print("baseDir="); pw.println(appInfo.sourceDir); 432 if (!Objects.equals(appInfo.sourceDir, appInfo.publicSourceDir)) { 433 pw.print(prefix); pw.print("resDir="); pw.println(appInfo.publicSourceDir); 434 } 435 pw.print(prefix); pw.print("dataDir="); pw.println(appInfo.dataDir); 436 } 437 pw.print(prefix); pw.print("app="); pw.println(app); 438 if (isolatedProc != null) { 439 pw.print(prefix); pw.print("isolatedProc="); pw.println(isolatedProc); 440 } 441 if (allowlistManager) { 442 pw.print(prefix); pw.print("allowlistManager="); pw.println(allowlistManager); 443 } 444 if (mIsAllowedBgActivityStartsByBinding) { 445 pw.print(prefix); pw.print("mIsAllowedBgActivityStartsByBinding="); 446 pw.println(mIsAllowedBgActivityStartsByBinding); 447 } 448 if (mIsAllowedBgActivityStartsByStart) { 449 pw.print(prefix); pw.print("mIsAllowedBgActivityStartsByStart="); 450 pw.println(mIsAllowedBgActivityStartsByStart); 451 } 452 pw.print(prefix); pw.print("allowWhileInUsePermissionInFgs="); 453 pw.println(mAllowWhileInUsePermissionInFgs); 454 pw.print(prefix); pw.print("recentCallingPackage="); 455 pw.println(mRecentCallingPackage); 456 pw.print(prefix); pw.print("recentCallingUid="); 457 pw.println(mRecentCallingUid); 458 pw.print(prefix); pw.print("allowStartForeground="); 459 pw.println(mAllowStartForeground); 460 pw.print(prefix); pw.print("startForegroundCount="); 461 pw.println(mStartForegroundCount); 462 pw.print(prefix); pw.print("infoAllowStartForeground="); 463 pw.println(mInfoAllowStartForeground); 464 if (delayed) { 465 pw.print(prefix); pw.print("delayed="); pw.println(delayed); 466 } 467 if (isForeground || foregroundId != 0) { 468 pw.print(prefix); pw.print("isForeground="); pw.print(isForeground); 469 pw.print(" foregroundId="); pw.print(foregroundId); 470 pw.print(" foregroundNoti="); pw.println(foregroundNoti); 471 } 472 pw.print(prefix); pw.print("createTime="); 473 TimeUtils.formatDuration(createRealTime, nowReal, pw); 474 pw.print(" startingBgTimeout="); 475 TimeUtils.formatDuration(startingBgTimeout, now, pw); 476 pw.println(); 477 pw.print(prefix); pw.print("lastActivity="); 478 TimeUtils.formatDuration(lastActivity, now, pw); 479 pw.print(" restartTime="); 480 TimeUtils.formatDuration(restartTime, now, pw); 481 pw.print(" createdFromFg="); pw.println(createdFromFg); 482 if (pendingConnectionGroup != 0) { 483 pw.print(prefix); pw.print(" pendingConnectionGroup="); 484 pw.print(pendingConnectionGroup); 485 pw.print(" Importance="); pw.println(pendingConnectionImportance); 486 } 487 if (startRequested || delayedStop || lastStartId != 0) { 488 pw.print(prefix); pw.print("startRequested="); pw.print(startRequested); 489 pw.print(" delayedStop="); pw.print(delayedStop); 490 pw.print(" stopIfKilled="); pw.print(stopIfKilled); 491 pw.print(" callStart="); pw.print(callStart); 492 pw.print(" lastStartId="); pw.println(lastStartId); 493 } 494 if (executeNesting != 0) { 495 pw.print(prefix); pw.print("executeNesting="); pw.print(executeNesting); 496 pw.print(" executeFg="); pw.print(executeFg); 497 pw.print(" executingStart="); 498 TimeUtils.formatDuration(executingStart, now, pw); 499 pw.println(); 500 } 501 if (destroying || destroyTime != 0) { 502 pw.print(prefix); pw.print("destroying="); pw.print(destroying); 503 pw.print(" destroyTime="); 504 TimeUtils.formatDuration(destroyTime, now, pw); 505 pw.println(); 506 } 507 if (crashCount != 0 || restartCount != 0 508 || restartDelay != 0 || nextRestartTime != 0) { 509 pw.print(prefix); pw.print("restartCount="); pw.print(restartCount); 510 pw.print(" restartDelay="); 511 TimeUtils.formatDuration(restartDelay, now, pw); 512 pw.print(" nextRestartTime="); 513 TimeUtils.formatDuration(nextRestartTime, now, pw); 514 pw.print(" crashCount="); pw.println(crashCount); 515 } 516 if (deliveredStarts.size() > 0) { 517 pw.print(prefix); pw.println("Delivered Starts:"); 518 dumpStartList(pw, prefix, deliveredStarts, now); 519 } 520 if (pendingStarts.size() > 0) { 521 pw.print(prefix); pw.println("Pending Starts:"); 522 dumpStartList(pw, prefix, pendingStarts, 0); 523 } 524 if (bindings.size() > 0) { 525 pw.print(prefix); pw.println("Bindings:"); 526 for (int i=0; i<bindings.size(); i++) { 527 IntentBindRecord b = bindings.valueAt(i); 528 pw.print(prefix); pw.print("* IntentBindRecord{"); 529 pw.print(Integer.toHexString(System.identityHashCode(b))); 530 if ((b.collectFlags()&Context.BIND_AUTO_CREATE) != 0) { 531 pw.append(" CREATE"); 532 } 533 pw.println("}:"); 534 b.dumpInService(pw, prefix + " "); 535 } 536 } 537 if (connections.size() > 0) { 538 pw.print(prefix); pw.println("All Connections:"); 539 for (int conni=0; conni<connections.size(); conni++) { 540 ArrayList<ConnectionRecord> c = connections.valueAt(conni); 541 for (int i=0; i<c.size(); i++) { 542 pw.print(prefix); pw.print(" "); pw.println(c.get(i)); 543 } 544 } 545 } 546 } 547 ServiceRecord(ActivityManagerService ams, ComponentName name, ComponentName instanceName, String definingPackageName, int definingUid, Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg, Runnable restarter)548 ServiceRecord(ActivityManagerService ams, ComponentName name, 549 ComponentName instanceName, String definingPackageName, int definingUid, 550 Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg, 551 Runnable restarter) { 552 this.ams = ams; 553 this.name = name; 554 this.instanceName = instanceName; 555 shortInstanceName = instanceName.flattenToShortString(); 556 this.definingPackageName = definingPackageName; 557 this.definingUid = definingUid; 558 this.intent = intent; 559 serviceInfo = sInfo; 560 appInfo = sInfo.applicationInfo; 561 packageName = sInfo.applicationInfo.packageName; 562 if ((sInfo.flags & ServiceInfo.FLAG_ISOLATED_PROCESS) != 0) { 563 processName = sInfo.processName + ":" + instanceName.getClassName(); 564 } else { 565 processName = sInfo.processName; 566 } 567 permission = sInfo.permission; 568 exported = sInfo.exported; 569 this.restarter = restarter; 570 createRealTime = SystemClock.elapsedRealtime(); 571 lastActivity = SystemClock.uptimeMillis(); 572 userId = UserHandle.getUserId(appInfo.uid); 573 createdFromFg = callerIsFg; 574 updateKeepWarmLocked(); 575 } 576 getTracker()577 public ServiceState getTracker() { 578 if (tracker != null) { 579 return tracker; 580 } 581 if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) { 582 tracker = ams.mProcessStats.getServiceState(serviceInfo.packageName, 583 serviceInfo.applicationInfo.uid, 584 serviceInfo.applicationInfo.longVersionCode, 585 serviceInfo.processName, serviceInfo.name); 586 tracker.applyNewOwner(this); 587 } 588 return tracker; 589 } 590 forceClearTracker()591 public void forceClearTracker() { 592 if (tracker != null) { 593 tracker.clearCurrentOwner(this, true); 594 tracker = null; 595 } 596 } 597 makeRestarting(int memFactor, long now)598 public void makeRestarting(int memFactor, long now) { 599 if (restartTracker == null) { 600 if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) { 601 restartTracker = ams.mProcessStats.getServiceState( 602 serviceInfo.packageName, 603 serviceInfo.applicationInfo.uid, 604 serviceInfo.applicationInfo.longVersionCode, 605 serviceInfo.processName, serviceInfo.name); 606 } 607 if (restartTracker == null) { 608 return; 609 } 610 } 611 restartTracker.setRestarting(true, memFactor, now); 612 } 613 setProcess(ProcessRecord proc, IApplicationThread thread, int pid, UidRecord uidRecord)614 public void setProcess(ProcessRecord proc, IApplicationThread thread, int pid, 615 UidRecord uidRecord) { 616 if (proc != null) { 617 // We're starting a new process for this service, but a previous one is allowed to start 618 // background activities. Remove that ability now (unless the new process is the same as 619 // the previous one, which is a common case). 620 if (mAppForAllowingBgActivityStartsByStart != null) { 621 if (mAppForAllowingBgActivityStartsByStart != proc) { 622 mAppForAllowingBgActivityStartsByStart 623 .removeAllowBackgroundActivityStartsToken(this); 624 ams.mHandler.removeCallbacks(mCleanUpAllowBgActivityStartsByStartCallback); 625 } 626 } 627 // Make sure the cleanup callback knows about the new process. 628 mAppForAllowingBgActivityStartsByStart = mIsAllowedBgActivityStartsByStart 629 ? proc : null; 630 if (mIsAllowedBgActivityStartsByStart 631 || mIsAllowedBgActivityStartsByBinding) { 632 proc.addOrUpdateAllowBackgroundActivityStartsToken(this, 633 getExclusiveOriginatingToken()); 634 } else { 635 proc.removeAllowBackgroundActivityStartsToken(this); 636 } 637 } 638 if (app != null && app != proc) { 639 // If the old app is allowed to start bg activities because of a service start, leave it 640 // that way until the cleanup callback runs. Otherwise we can remove its bg activity 641 // start ability immediately (it can't be bound now). 642 if (!mIsAllowedBgActivityStartsByStart) { 643 app.removeAllowBackgroundActivityStartsToken(this); 644 } 645 app.mServices.updateBoundClientUids(); 646 } 647 app = proc; 648 if (pendingConnectionGroup > 0 && proc != null) { 649 final ProcessServiceRecord psr = proc.mServices; 650 psr.setConnectionService(this); 651 psr.setConnectionGroup(pendingConnectionGroup); 652 psr.setConnectionImportance(pendingConnectionImportance); 653 pendingConnectionGroup = pendingConnectionImportance = 0; 654 } 655 if (ActivityManagerService.TRACK_PROCSTATS_ASSOCIATIONS) { 656 for (int conni = connections.size() - 1; conni >= 0; conni--) { 657 ArrayList<ConnectionRecord> cr = connections.valueAt(conni); 658 for (int i = 0; i < cr.size(); i++) { 659 final ConnectionRecord conn = cr.get(i); 660 if (proc != null) { 661 conn.startAssociationIfNeeded(); 662 } else { 663 conn.stopAssociation(); 664 } 665 } 666 } 667 } 668 if (proc != null) { 669 proc.mServices.updateBoundClientUids(); 670 } 671 } 672 getConnections()673 ArrayMap<IBinder, ArrayList<ConnectionRecord>> getConnections() { 674 return connections; 675 } 676 addConnection(IBinder binder, ConnectionRecord c)677 void addConnection(IBinder binder, ConnectionRecord c) { 678 ArrayList<ConnectionRecord> clist = connections.get(binder); 679 if (clist == null) { 680 clist = new ArrayList<>(); 681 connections.put(binder, clist); 682 } 683 clist.add(c); 684 685 // if we have a process attached, add bound client uid of this connection to it 686 if (app != null) { 687 app.mServices.addBoundClientUid(c.clientUid); 688 } 689 } 690 removeConnection(IBinder binder)691 void removeConnection(IBinder binder) { 692 connections.remove(binder); 693 // if we have a process attached, tell it to update the state of bound clients 694 if (app != null) { 695 app.mServices.updateBoundClientUids(); 696 } 697 } 698 699 /** 700 * @return {@code true} if the killed service which was started by {@link Context#startService} 701 * has no reason to start again. Note this condition doesn't consider the bindings. 702 */ canStopIfKilled(boolean isStartCanceled)703 boolean canStopIfKilled(boolean isStartCanceled) { 704 return startRequested && (stopIfKilled || isStartCanceled) && pendingStarts.isEmpty(); 705 } 706 updateIsAllowedBgActivityStartsByBinding()707 void updateIsAllowedBgActivityStartsByBinding() { 708 boolean isAllowedByBinding = false; 709 for (int conni = connections.size() - 1; conni >= 0; conni--) { 710 ArrayList<ConnectionRecord> cr = connections.valueAt(conni); 711 for (int i = 0; i < cr.size(); i++) { 712 if ((cr.get(i).flags & Context.BIND_ALLOW_BACKGROUND_ACTIVITY_STARTS) != 0) { 713 isAllowedByBinding = true; 714 break; 715 } 716 } 717 if (isAllowedByBinding) { 718 break; 719 } 720 } 721 setAllowedBgActivityStartsByBinding(isAllowedByBinding); 722 } 723 setAllowedBgActivityStartsByBinding(boolean newValue)724 void setAllowedBgActivityStartsByBinding(boolean newValue) { 725 mIsAllowedBgActivityStartsByBinding = newValue; 726 updateParentProcessBgActivityStartsToken(); 727 } 728 729 /** 730 * Called when the service is started with allowBackgroundActivityStarts set. We allow 731 * it for background activity starts, setting up a callback to remove this ability after a 732 * timeout. Note that the ability for starting background activities persists for the process 733 * even if the service is subsequently stopped. 734 */ allowBgActivityStartsOnServiceStart(@ullable IBinder originatingToken)735 void allowBgActivityStartsOnServiceStart(@Nullable IBinder originatingToken) { 736 mBgActivityStartsByStartOriginatingTokens.add(originatingToken); 737 setAllowedBgActivityStartsByStart(true); 738 if (app != null) { 739 mAppForAllowingBgActivityStartsByStart = app; 740 } 741 742 // This callback is stateless, so we create it once when we first need it. 743 if (mCleanUpAllowBgActivityStartsByStartCallback == null) { 744 mCleanUpAllowBgActivityStartsByStartCallback = () -> { 745 synchronized (ams) { 746 mBgActivityStartsByStartOriginatingTokens.remove(0); 747 if (!mBgActivityStartsByStartOriginatingTokens.isEmpty()) { 748 // There are other callbacks in the queue, let's just update the originating 749 // token 750 if (mIsAllowedBgActivityStartsByStart) { 751 // mAppForAllowingBgActivityStartsByStart can be null here for example 752 // if get 2 calls to allowBgActivityStartsOnServiceStart() without a 753 // process attached to this ServiceRecord, so we need to perform a null 754 // check here. 755 if (mAppForAllowingBgActivityStartsByStart != null) { 756 mAppForAllowingBgActivityStartsByStart 757 .addOrUpdateAllowBackgroundActivityStartsToken( 758 this, getExclusiveOriginatingToken()); 759 } 760 } else { 761 Slog.wtf(TAG, 762 "Service callback to revoke bg activity starts by service " 763 + "start triggered but " 764 + "mIsAllowedBgActivityStartsByStart = false. This " 765 + "should never happen."); 766 } 767 } else { 768 // Last callback on the queue 769 if (app == mAppForAllowingBgActivityStartsByStart) { 770 // The process we allowed is still running the service. We remove 771 // the ability by start, but it may still be allowed via bound 772 // connections. 773 setAllowedBgActivityStartsByStart(false); 774 } else if (mAppForAllowingBgActivityStartsByStart != null) { 775 // The process we allowed is not running the service. It therefore can't 776 // be bound so we can unconditionally remove the ability. 777 mAppForAllowingBgActivityStartsByStart 778 .removeAllowBackgroundActivityStartsToken(ServiceRecord.this); 779 } 780 mAppForAllowingBgActivityStartsByStart = null; 781 } 782 } 783 }; 784 } 785 786 // Existing callbacks will only update the originating token, only when the last callback is 787 // executed is the grant revoked. 788 ams.mHandler.postDelayed(mCleanUpAllowBgActivityStartsByStartCallback, 789 ams.mConstants.SERVICE_BG_ACTIVITY_START_TIMEOUT); 790 } 791 setAllowedBgActivityStartsByStart(boolean newValue)792 private void setAllowedBgActivityStartsByStart(boolean newValue) { 793 mIsAllowedBgActivityStartsByStart = newValue; 794 updateParentProcessBgActivityStartsToken(); 795 } 796 797 /** 798 * Whether the process this service runs in should be temporarily allowed to start 799 * activities from background depends on the current state of both 800 * {@code mIsAllowedBgActivityStartsByStart} and 801 * {@code mIsAllowedBgActivityStartsByBinding}. If either is true, this ServiceRecord 802 * should be contributing as a token in parent ProcessRecord. 803 * 804 * @see com.android.server.am.ProcessRecord#addOrUpdateAllowBackgroundActivityStartsToken( 805 * Binder, IBinder) 806 * @see com.android.server.am.ProcessRecord#removeAllowBackgroundActivityStartsToken(Binder) 807 */ updateParentProcessBgActivityStartsToken()808 private void updateParentProcessBgActivityStartsToken() { 809 if (app == null) { 810 return; 811 } 812 if (mIsAllowedBgActivityStartsByStart || mIsAllowedBgActivityStartsByBinding) { 813 // if the token is already there it's safe to "re-add it" - we're dealing with 814 // a set of Binder objects 815 app.addOrUpdateAllowBackgroundActivityStartsToken(this, getExclusiveOriginatingToken()); 816 } else { 817 app.removeAllowBackgroundActivityStartsToken(this); 818 } 819 } 820 821 /** 822 * Returns the originating token if that's the only reason background activity starts are 823 * allowed. In order for that to happen the service has to be allowed only due to starts, since 824 * bindings are not associated with originating tokens, and all the start tokens have to be the 825 * same and there can't be any null originating token in the queue. 826 * 827 * Originating tokens are optional, so the caller could provide null when it allows bg activity 828 * starts. 829 */ 830 @Nullable getExclusiveOriginatingToken()831 private IBinder getExclusiveOriginatingToken() { 832 if (mIsAllowedBgActivityStartsByBinding 833 || mBgActivityStartsByStartOriginatingTokens.isEmpty()) { 834 return null; 835 } 836 IBinder firstToken = mBgActivityStartsByStartOriginatingTokens.get(0); 837 for (int i = 1, n = mBgActivityStartsByStartOriginatingTokens.size(); i < n; i++) { 838 IBinder token = mBgActivityStartsByStartOriginatingTokens.get(i); 839 if (token != firstToken) { 840 return null; 841 } 842 } 843 return firstToken; 844 } 845 846 @GuardedBy("ams") updateKeepWarmLocked()847 void updateKeepWarmLocked() { 848 mKeepWarming = ams.mConstants.KEEP_WARMING_SERVICES.contains(name) 849 && (ams.mUserController.getCurrentUserId() == userId 850 || ams.mUserController.isCurrentProfile(userId) 851 || ams.isSingleton(processName, appInfo, instanceName.getClassName(), 852 serviceInfo.flags)); 853 } 854 retrieveAppBindingLocked(Intent intent, ProcessRecord app)855 public AppBindRecord retrieveAppBindingLocked(Intent intent, 856 ProcessRecord app) { 857 Intent.FilterComparison filter = new Intent.FilterComparison(intent); 858 IntentBindRecord i = bindings.get(filter); 859 if (i == null) { 860 i = new IntentBindRecord(this, filter); 861 bindings.put(filter, i); 862 } 863 AppBindRecord a = i.apps.get(app); 864 if (a != null) { 865 return a; 866 } 867 a = new AppBindRecord(this, i, app); 868 i.apps.put(app, a); 869 return a; 870 } 871 hasAutoCreateConnections()872 public boolean hasAutoCreateConnections() { 873 // XXX should probably keep a count of the number of auto-create 874 // connections directly in the service. 875 for (int conni=connections.size()-1; conni>=0; conni--) { 876 ArrayList<ConnectionRecord> cr = connections.valueAt(conni); 877 for (int i=0; i<cr.size(); i++) { 878 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) { 879 return true; 880 } 881 } 882 } 883 return false; 884 } 885 updateAllowlistManager()886 public void updateAllowlistManager() { 887 allowlistManager = false; 888 for (int conni=connections.size()-1; conni>=0; conni--) { 889 ArrayList<ConnectionRecord> cr = connections.valueAt(conni); 890 for (int i=0; i<cr.size(); i++) { 891 if ((cr.get(i).flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) { 892 allowlistManager = true; 893 return; 894 } 895 } 896 } 897 } 898 resetRestartCounter()899 public void resetRestartCounter() { 900 restartCount = 0; 901 restartDelay = 0; 902 restartTime = 0; 903 } 904 findDeliveredStart(int id, boolean taskRemoved, boolean remove)905 public StartItem findDeliveredStart(int id, boolean taskRemoved, boolean remove) { 906 final int N = deliveredStarts.size(); 907 for (int i=0; i<N; i++) { 908 StartItem si = deliveredStarts.get(i); 909 if (si.id == id && si.taskRemoved == taskRemoved) { 910 if (remove) deliveredStarts.remove(i); 911 return si; 912 } 913 } 914 915 return null; 916 } 917 getLastStartId()918 public int getLastStartId() { 919 return lastStartId; 920 } 921 makeNextStartId()922 public int makeNextStartId() { 923 lastStartId++; 924 if (lastStartId < 1) { 925 lastStartId = 1; 926 } 927 return lastStartId; 928 } 929 postNotification()930 public void postNotification() { 931 if (isForeground && foregroundNoti != null && app != null) { 932 final int appUid = appInfo.uid; 933 final int appPid = app.getPid(); 934 // Do asynchronous communication with notification manager to 935 // avoid deadlocks. 936 final String localPackageName = packageName; 937 final int localForegroundId = foregroundId; 938 final Notification _foregroundNoti = foregroundNoti; 939 final ServiceRecord record = this; 940 if (DEBUG_FOREGROUND_SERVICE) { 941 Slog.d(TAG, "Posting notification " + _foregroundNoti 942 + " for foreground service " + this); 943 } 944 ams.mHandler.post(new Runnable() { 945 public void run() { 946 NotificationManagerInternal nm = LocalServices.getService( 947 NotificationManagerInternal.class); 948 if (nm == null) { 949 return; 950 } 951 Notification localForegroundNoti = _foregroundNoti; 952 try { 953 if (localForegroundNoti.getSmallIcon() == null) { 954 // It is not correct for the caller to not supply a notification 955 // icon, but this used to be able to slip through, so for 956 // those dirty apps we will create a notification clearly 957 // blaming the app. 958 Slog.v(TAG, "Attempted to start a foreground service (" 959 + shortInstanceName 960 + ") with a broken notification (no icon: " 961 + localForegroundNoti 962 + ")"); 963 964 CharSequence appName = appInfo.loadLabel( 965 ams.mContext.getPackageManager()); 966 if (appName == null) { 967 appName = appInfo.packageName; 968 } 969 Context ctx = null; 970 try { 971 ctx = ams.mContext.createPackageContextAsUser( 972 appInfo.packageName, 0, new UserHandle(userId)); 973 974 Notification.Builder notiBuilder = new Notification.Builder(ctx, 975 localForegroundNoti.getChannelId()); 976 977 // it's ugly, but it clearly identifies the app 978 notiBuilder.setSmallIcon(appInfo.icon); 979 980 // mark as foreground 981 notiBuilder.setFlag(Notification.FLAG_FOREGROUND_SERVICE, true); 982 983 Intent runningIntent = new Intent( 984 Settings.ACTION_APPLICATION_DETAILS_SETTINGS); 985 runningIntent.setData(Uri.fromParts("package", 986 appInfo.packageName, null)); 987 PendingIntent pi = PendingIntent.getActivityAsUser(ams.mContext, 0, 988 runningIntent, FLAG_UPDATE_CURRENT | FLAG_IMMUTABLE, null, 989 UserHandle.of(userId)); 990 notiBuilder.setColor(ams.mContext.getColor( 991 com.android.internal 992 .R.color.system_notification_accent_color)); 993 notiBuilder.setContentTitle( 994 ams.mContext.getString( 995 com.android.internal.R.string 996 .app_running_notification_title, 997 appName)); 998 notiBuilder.setContentText( 999 ams.mContext.getString( 1000 com.android.internal.R.string 1001 .app_running_notification_text, 1002 appName)); 1003 notiBuilder.setContentIntent(pi); 1004 1005 localForegroundNoti = notiBuilder.build(); 1006 } catch (PackageManager.NameNotFoundException e) { 1007 } 1008 } 1009 if (nm.getNotificationChannel(localPackageName, appUid, 1010 localForegroundNoti.getChannelId()) == null) { 1011 int targetSdkVersion = Build.VERSION_CODES.O_MR1; 1012 try { 1013 final ApplicationInfo applicationInfo = 1014 ams.mContext.getPackageManager().getApplicationInfoAsUser( 1015 appInfo.packageName, 0, userId); 1016 targetSdkVersion = applicationInfo.targetSdkVersion; 1017 } catch (PackageManager.NameNotFoundException e) { 1018 } 1019 if (targetSdkVersion >= Build.VERSION_CODES.O_MR1) { 1020 throw new RuntimeException( 1021 "invalid channel for service notification: " 1022 + foregroundNoti); 1023 } 1024 } 1025 if (localForegroundNoti.getSmallIcon() == null) { 1026 // Notifications whose icon is 0 are defined to not show 1027 // a notification. We don't want to 1028 // just ignore it, we want to prevent the service from 1029 // being foreground. 1030 throw new RuntimeException("invalid service notification: " 1031 + foregroundNoti); 1032 } 1033 nm.enqueueNotification(localPackageName, localPackageName, 1034 appUid, appPid, null, localForegroundId, localForegroundNoti, 1035 userId); 1036 1037 foregroundNoti = localForegroundNoti; // save it for amending next time 1038 } catch (RuntimeException e) { 1039 Slog.w(TAG, "Error showing notification for service", e); 1040 // If it gave us a garbage notification, it doesn't 1041 // get to be foreground. 1042 ams.mServices.killMisbehavingService(record, 1043 appUid, appPid, localPackageName, 1044 CannotPostForegroundServiceNotificationException.TYPE_ID); 1045 } 1046 } 1047 }); 1048 } 1049 } 1050 cancelNotification()1051 public void cancelNotification() { 1052 // Do asynchronous communication with notification manager to 1053 // avoid deadlocks. 1054 final String localPackageName = packageName; 1055 final int localForegroundId = foregroundId; 1056 final int appUid = appInfo.uid; 1057 final int appPid = app != null ? app.getPid() : 0; 1058 ams.mHandler.post(new Runnable() { 1059 public void run() { 1060 NotificationManagerInternal nm = LocalServices.getService( 1061 NotificationManagerInternal.class); 1062 if (nm == null) { 1063 return; 1064 } 1065 try { 1066 nm.cancelNotification(localPackageName, localPackageName, appUid, appPid, 1067 null, localForegroundId, userId); 1068 } catch (RuntimeException e) { 1069 Slog.w(TAG, "Error canceling notification for service", e); 1070 } 1071 } 1072 }); 1073 } 1074 stripForegroundServiceFlagFromNotification()1075 public void stripForegroundServiceFlagFromNotification() { 1076 final int localForegroundId = foregroundId; 1077 final int localUserId = userId; 1078 final String localPackageName = packageName; 1079 1080 // Do asynchronous communication with notification manager to 1081 // avoid deadlocks. 1082 ams.mHandler.post(new Runnable() { 1083 @Override 1084 public void run() { 1085 NotificationManagerInternal nmi = LocalServices.getService( 1086 NotificationManagerInternal.class); 1087 if (nmi == null) { 1088 return; 1089 } 1090 nmi.removeForegroundServiceFlagFromNotification(localPackageName, localForegroundId, 1091 localUserId); 1092 } 1093 }); 1094 } 1095 clearDeliveredStartsLocked()1096 public void clearDeliveredStartsLocked() { 1097 for (int i=deliveredStarts.size()-1; i>=0; i--) { 1098 deliveredStarts.get(i).removeUriPermissionsLocked(); 1099 } 1100 deliveredStarts.clear(); 1101 } 1102 toString()1103 public String toString() { 1104 if (stringName != null) { 1105 return stringName; 1106 } 1107 StringBuilder sb = new StringBuilder(128); 1108 sb.append("ServiceRecord{") 1109 .append(Integer.toHexString(System.identityHashCode(this))) 1110 .append(" u").append(userId) 1111 .append(' ').append(shortInstanceName).append('}'); 1112 return stringName = sb.toString(); 1113 } 1114 getComponentName()1115 public ComponentName getComponentName() { 1116 return name; 1117 } 1118 } 1119