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