1 /* 2 * Copyright (C) 2020 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.ProcessMemoryState.HOSTING_COMPONENT_TYPE_BOUND_SERVICE; 20 import static android.app.ProcessMemoryState.HOSTING_COMPONENT_TYPE_FOREGROUND_SERVICE; 21 22 import android.app.ActivityManager; 23 import android.content.Context; 24 import android.content.pm.ServiceInfo; 25 import android.os.IBinder; 26 import android.os.SystemClock; 27 import android.util.ArrayMap; 28 import android.util.ArraySet; 29 30 import com.android.internal.annotations.GuardedBy; 31 import com.android.server.wm.WindowProcessController; 32 33 import java.io.PrintWriter; 34 import java.util.ArrayList; 35 36 /** 37 * The state info of all services in the process. 38 */ 39 final class ProcessServiceRecord { 40 /** 41 * Are there any client services with activities? 42 */ 43 private boolean mHasClientActivities; 44 45 /** 46 * Running any services that are foreground? 47 */ 48 private boolean mHasForegroundServices; 49 50 /** 51 * Last reported state of whether it's running any services that are foreground. 52 */ 53 private boolean mRepHasForegroundServices; 54 55 /** 56 * Running any services that are almost perceptible (started with 57 * {@link Context#BIND_ALMOST_PERCEPTIBLE} while the app was on TOP)? 58 */ 59 private boolean mHasTopStartedAlmostPerceptibleServices; 60 61 /** 62 * The latest value of {@link ServiceRecord#lastTopAlmostPerceptibleBindRequestUptimeMs} among 63 * the currently running services. 64 */ 65 private long mLastTopStartedAlmostPerceptibleBindRequestUptimeMs; 66 67 /** 68 * Service that applied current connectionGroup/Importance. 69 */ 70 private ServiceRecord mConnectionService; 71 72 /** 73 * Last group set by a connection. 74 */ 75 private int mConnectionGroup; 76 77 /** 78 * Last importance set by a connection. 79 */ 80 private int mConnectionImportance; 81 82 /** 83 * The OR'ed foreground service types that are running on this process. 84 * Note, because TYPE_NONE (==0) is also a valid type for pre-U apps, this field doesn't tell 85 * if the process has any TYPE_NONE FGS or not, but {@link #mHasTypeNoneFgs} will be set 86 * in that case. 87 */ 88 private int mFgServiceTypes; 89 90 /** 91 * Whether the process has any foreground services of TYPE_NONE running. 92 * @see #mFgServiceTypes 93 */ 94 private boolean mHasTypeNoneFgs; 95 96 /** 97 * Last reported foreground service types. 98 */ 99 private int mRepFgServiceTypes; 100 101 /** 102 * Bound using BIND_ABOVE_CLIENT, so want to be lower. 103 */ 104 private boolean mHasAboveClient; 105 106 /** 107 * Bound using BIND_TREAT_LIKE_ACTIVITY. 108 */ 109 private boolean mTreatLikeActivity; 110 111 /** 112 * Do we need to be executing services in the foreground? 113 */ 114 private boolean mExecServicesFg; 115 116 /** 117 * App is allowed to manage allowlists such as temporary Power Save mode allowlist. 118 */ 119 boolean mAllowlistManager; 120 121 /** 122 * All ServiceRecord running in this process. 123 */ 124 final ArraySet<ServiceRecord> mServices = new ArraySet<>(); 125 126 /** 127 * Services that are currently executing code (need to remain foreground). 128 */ 129 private final ArraySet<ServiceRecord> mExecutingServices = new ArraySet<>(); 130 131 /** 132 * All ConnectionRecord this process holds. 133 */ 134 private final ArraySet<ConnectionRecord> mConnections = new ArraySet<>(); 135 136 /** 137 * A set of UIDs of all bound clients. 138 */ 139 private ArraySet<Integer> mBoundClientUids = new ArraySet<>(); 140 141 final ProcessRecord mApp; 142 143 private final ActivityManagerService mService; 144 ProcessServiceRecord(ProcessRecord app)145 ProcessServiceRecord(ProcessRecord app) { 146 mApp = app; 147 mService = app.mService; 148 } 149 setHasClientActivities(boolean hasClientActivities)150 void setHasClientActivities(boolean hasClientActivities) { 151 mHasClientActivities = hasClientActivities; 152 mApp.getWindowProcessController().setHasClientActivities(hasClientActivities); 153 } 154 hasClientActivities()155 boolean hasClientActivities() { 156 return mHasClientActivities; 157 } 158 setHasForegroundServices(boolean hasForegroundServices, int fgServiceTypes, boolean hasTypeNoneFgs)159 void setHasForegroundServices(boolean hasForegroundServices, int fgServiceTypes, 160 boolean hasTypeNoneFgs) { 161 // hasForegroundServices should be the same as "either it has any FGS types, or none types". 162 // We still take this as a parameter because it's used in the callsite... 163 if (ActivityManagerDebugConfig.DEBUG_SERVICE 164 && hasForegroundServices != ((fgServiceTypes != 0) || hasTypeNoneFgs)) { 165 throw new IllegalStateException("hasForegroundServices mismatch"); 166 } 167 168 mHasForegroundServices = hasForegroundServices; 169 mFgServiceTypes = fgServiceTypes; 170 mHasTypeNoneFgs = hasTypeNoneFgs; 171 mApp.getWindowProcessController().setHasForegroundServices(hasForegroundServices); 172 if (hasForegroundServices) { 173 mApp.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_FOREGROUND_SERVICE); 174 } else { 175 mApp.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_FOREGROUND_SERVICE); 176 } 177 } 178 179 /** 180 * @return true if this process has any foreground services (even timed-out short-FGS) 181 */ hasForegroundServices()182 boolean hasForegroundServices() { 183 return mHasForegroundServices; 184 } 185 setHasReportedForegroundServices(boolean hasForegroundServices)186 void setHasReportedForegroundServices(boolean hasForegroundServices) { 187 mRepHasForegroundServices = hasForegroundServices; 188 } 189 hasReportedForegroundServices()190 boolean hasReportedForegroundServices() { 191 return mRepHasForegroundServices; 192 } 193 194 /** 195 * Returns the FGS typps, but it doesn't tell if the types include "NONE" or not, so 196 * do not use it outside of this class. 197 */ getForegroundServiceTypes()198 private int getForegroundServiceTypes() { 199 return mHasForegroundServices ? mFgServiceTypes : 0; 200 } 201 areForegroundServiceTypesSame(@erviceInfo.ForegroundServiceType int types, boolean hasTypeNoneFgs)202 boolean areForegroundServiceTypesSame(@ServiceInfo.ForegroundServiceType int types, 203 boolean hasTypeNoneFgs) { 204 return ((getForegroundServiceTypes() & types) == types) 205 && (mHasTypeNoneFgs == hasTypeNoneFgs); 206 } 207 208 /** 209 * @return true if the fgs types includes any of the given types. 210 * (wouldn't work for TYPE_NONE, which is 0) 211 */ containsAnyForegroundServiceTypes(@erviceInfo.ForegroundServiceType int types)212 boolean containsAnyForegroundServiceTypes(@ServiceInfo.ForegroundServiceType int types) { 213 return (getForegroundServiceTypes() & types) != 0; 214 } 215 216 /** 217 * @return true if the process has any FGS that are _not_ a "short" FGS. 218 */ hasNonShortForegroundServices()219 boolean hasNonShortForegroundServices() { 220 if (!mHasForegroundServices) { 221 return false; // Process has no FGS running. 222 } 223 // Does the process has any FGS of TYPE_NONE? 224 if (mHasTypeNoneFgs) { 225 return true; 226 } 227 // If not, we can just check mFgServiceTypes. 228 return mFgServiceTypes != ServiceInfo.FOREGROUND_SERVICE_TYPE_SHORT_SERVICE; 229 } 230 231 /** 232 * @return if this process: 233 * - has at least one short-FGS 234 * - has no other types of FGS 235 * - and all the short-FGSes are procstate-timed out. 236 */ areAllShortForegroundServicesProcstateTimedOut(long nowUptime)237 boolean areAllShortForegroundServicesProcstateTimedOut(long nowUptime) { 238 if (!mHasForegroundServices) { // Process has no FGS? 239 return false; 240 } 241 if (hasNonShortForegroundServices()) { // Any non-short FGS running? 242 return false; 243 } 244 // Now we need to look at all short-FGS within the process and see if all of them are 245 // procstate-timed-out or not. 246 for (int i = mServices.size() - 1; i >= 0; i--) { 247 final ServiceRecord sr = mServices.valueAt(i); 248 if (!sr.isShortFgs() || !sr.hasShortFgsInfo()) { 249 continue; 250 } 251 if (sr.getShortFgsInfo().getProcStateDemoteTime() >= nowUptime) { 252 return false; 253 } 254 } 255 return true; 256 } 257 getReportedForegroundServiceTypes()258 int getReportedForegroundServiceTypes() { 259 return mRepFgServiceTypes; 260 } 261 setReportedForegroundServiceTypes(int foregroundServiceTypes)262 void setReportedForegroundServiceTypes(int foregroundServiceTypes) { 263 mRepFgServiceTypes = foregroundServiceTypes; 264 } 265 getNumForegroundServices()266 int getNumForegroundServices() { 267 int count = 0; 268 for (int i = 0, serviceCount = mServices.size(); i < serviceCount; i++) { 269 if (mServices.valueAt(i).isForeground) { 270 count++; 271 } 272 } 273 return count; 274 } 275 updateHasTopStartedAlmostPerceptibleServices()276 void updateHasTopStartedAlmostPerceptibleServices() { 277 mHasTopStartedAlmostPerceptibleServices = false; 278 mLastTopStartedAlmostPerceptibleBindRequestUptimeMs = 0; 279 for (int s = mServices.size() - 1; s >= 0; --s) { 280 final ServiceRecord sr = mServices.valueAt(s); 281 mLastTopStartedAlmostPerceptibleBindRequestUptimeMs = Math.max( 282 mLastTopStartedAlmostPerceptibleBindRequestUptimeMs, 283 sr.lastTopAlmostPerceptibleBindRequestUptimeMs); 284 if (!mHasTopStartedAlmostPerceptibleServices && isAlmostPerceptible(sr)) { 285 mHasTopStartedAlmostPerceptibleServices = true; 286 } 287 } 288 } 289 isAlmostPerceptible(ServiceRecord record)290 private boolean isAlmostPerceptible(ServiceRecord record) { 291 if (record.lastTopAlmostPerceptibleBindRequestUptimeMs <= 0) { 292 return false; 293 } 294 final ArrayMap<IBinder, ArrayList<ConnectionRecord>> serviceConnections = 295 record.getConnections(); 296 for (int m = serviceConnections.size() - 1; m >= 0; --m) { 297 final ArrayList<ConnectionRecord> clist = serviceConnections.valueAt(m); 298 299 for (int c = clist.size() - 1; c >= 0; --c) { 300 final ConnectionRecord cr = clist.get(c); 301 if (cr.hasFlag(Context.BIND_ALMOST_PERCEPTIBLE)) { 302 return true; 303 } 304 } 305 } 306 return false; 307 } 308 hasTopStartedAlmostPerceptibleServices()309 boolean hasTopStartedAlmostPerceptibleServices() { 310 return mHasTopStartedAlmostPerceptibleServices 311 || (mLastTopStartedAlmostPerceptibleBindRequestUptimeMs > 0 312 && SystemClock.uptimeMillis() - mLastTopStartedAlmostPerceptibleBindRequestUptimeMs 313 < mService.mConstants.mServiceBindAlmostPerceptibleTimeoutMs); 314 } 315 getConnectionService()316 ServiceRecord getConnectionService() { 317 return mConnectionService; 318 } 319 setConnectionService(ServiceRecord connectionService)320 void setConnectionService(ServiceRecord connectionService) { 321 mConnectionService = connectionService; 322 } 323 getConnectionGroup()324 int getConnectionGroup() { 325 return mConnectionGroup; 326 } 327 setConnectionGroup(int connectionGroup)328 void setConnectionGroup(int connectionGroup) { 329 mConnectionGroup = connectionGroup; 330 } 331 getConnectionImportance()332 int getConnectionImportance() { 333 return mConnectionImportance; 334 } 335 setConnectionImportance(int connectionImportance)336 void setConnectionImportance(int connectionImportance) { 337 mConnectionImportance = connectionImportance; 338 } 339 updateHasAboveClientLocked()340 void updateHasAboveClientLocked() { 341 mHasAboveClient = false; 342 for (int i = mConnections.size() - 1; i >= 0; i--) { 343 ConnectionRecord cr = mConnections.valueAt(i); 344 if (cr.hasFlag(Context.BIND_ABOVE_CLIENT)) { 345 mHasAboveClient = true; 346 break; 347 } 348 } 349 } 350 setHasAboveClient(boolean hasAboveClient)351 void setHasAboveClient(boolean hasAboveClient) { 352 mHasAboveClient = hasAboveClient; 353 } 354 hasAboveClient()355 boolean hasAboveClient() { 356 return mHasAboveClient; 357 } 358 modifyRawOomAdj(int adj)359 int modifyRawOomAdj(int adj) { 360 if (mHasAboveClient) { 361 // If this process has bound to any services with BIND_ABOVE_CLIENT, 362 // then we need to drop its adjustment to be lower than the service's 363 // in order to honor the request. We want to drop it by one adjustment 364 // level... but there is special meaning applied to various levels so 365 // we will skip some of them. 366 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 367 // System process will not get dropped, ever 368 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 369 adj = ProcessList.VISIBLE_APP_ADJ; 370 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 371 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 372 } else if (adj < ProcessList.PERCEPTIBLE_LOW_APP_ADJ) { 373 adj = ProcessList.PERCEPTIBLE_LOW_APP_ADJ; 374 } else if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 375 adj = ProcessList.CACHED_APP_MIN_ADJ; 376 } else if (adj < ProcessList.CACHED_APP_MAX_ADJ) { 377 adj++; 378 } 379 } 380 return adj; 381 } 382 isTreatedLikeActivity()383 boolean isTreatedLikeActivity() { 384 return mTreatLikeActivity; 385 } 386 setTreatLikeActivity(boolean treatLikeActivity)387 void setTreatLikeActivity(boolean treatLikeActivity) { 388 mTreatLikeActivity = treatLikeActivity; 389 } 390 shouldExecServicesFg()391 boolean shouldExecServicesFg() { 392 return mExecServicesFg; 393 } 394 setExecServicesFg(boolean execServicesFg)395 void setExecServicesFg(boolean execServicesFg) { 396 mExecServicesFg = execServicesFg; 397 } 398 399 /** 400 * Records a service as running in the process. Note that this method does not actually start 401 * the service, but records the service as started for bookkeeping. 402 * 403 * @return true if the service was added, false otherwise. 404 */ startService(ServiceRecord record)405 boolean startService(ServiceRecord record) { 406 if (record == null) { 407 return false; 408 } 409 boolean added = mServices.add(record); 410 if (added && record.serviceInfo != null) { 411 mApp.getWindowProcessController().onServiceStarted(record.serviceInfo); 412 updateHostingComonentTypeForBindingsLocked(); 413 } 414 if (record.lastTopAlmostPerceptibleBindRequestUptimeMs > 0) { 415 mLastTopStartedAlmostPerceptibleBindRequestUptimeMs = Math.max( 416 mLastTopStartedAlmostPerceptibleBindRequestUptimeMs, 417 record.lastTopAlmostPerceptibleBindRequestUptimeMs); 418 if (!mHasTopStartedAlmostPerceptibleServices) { 419 mHasTopStartedAlmostPerceptibleServices = isAlmostPerceptible(record); 420 } 421 } 422 return added; 423 } 424 425 /** 426 * Records a service as stopped. Note that like {@link #startService(ServiceRecord)} this method 427 * does not actually stop the service, but records the service as stopped for bookkeeping. 428 * 429 * @return true if the service was removed, false otherwise. 430 */ stopService(ServiceRecord record)431 boolean stopService(ServiceRecord record) { 432 final boolean removed = mServices.remove(record); 433 if (record.lastTopAlmostPerceptibleBindRequestUptimeMs > 0) { 434 updateHasTopStartedAlmostPerceptibleServices(); 435 } 436 if (removed) { 437 updateHostingComonentTypeForBindingsLocked(); 438 } 439 return removed; 440 } 441 442 /** 443 * The same as calling {@link #stopService(ServiceRecord)} on all current running services. 444 */ stopAllServices()445 void stopAllServices() { 446 mServices.clear(); 447 updateHasTopStartedAlmostPerceptibleServices(); 448 } 449 450 /** 451 * Returns the number of services added with {@link #startService(ServiceRecord)} and not yet 452 * removed by a call to {@link #stopService(ServiceRecord)} or {@link #stopAllServices()}. 453 * 454 * @see #startService(ServiceRecord) 455 * @see #stopService(ServiceRecord) 456 */ numberOfRunningServices()457 int numberOfRunningServices() { 458 return mServices.size(); 459 } 460 461 /** 462 * Returns the service at the specified {@code index}. 463 * 464 * @see #numberOfRunningServices() 465 */ getRunningServiceAt(int index)466 ServiceRecord getRunningServiceAt(int index) { 467 return mServices.valueAt(index); 468 } 469 startExecutingService(ServiceRecord service)470 void startExecutingService(ServiceRecord service) { 471 mExecutingServices.add(service); 472 } 473 stopExecutingService(ServiceRecord service)474 void stopExecutingService(ServiceRecord service) { 475 mExecutingServices.remove(service); 476 } 477 stopAllExecutingServices()478 void stopAllExecutingServices() { 479 mExecutingServices.clear(); 480 } 481 getExecutingServiceAt(int index)482 ServiceRecord getExecutingServiceAt(int index) { 483 return mExecutingServices.valueAt(index); 484 } 485 numberOfExecutingServices()486 int numberOfExecutingServices() { 487 return mExecutingServices.size(); 488 } 489 addConnection(ConnectionRecord connection)490 void addConnection(ConnectionRecord connection) { 491 mConnections.add(connection); 492 } 493 removeConnection(ConnectionRecord connection)494 void removeConnection(ConnectionRecord connection) { 495 mConnections.remove(connection); 496 } 497 removeAllConnections()498 void removeAllConnections() { 499 mConnections.clear(); 500 } 501 getConnectionAt(int index)502 ConnectionRecord getConnectionAt(int index) { 503 return mConnections.valueAt(index); 504 } 505 numberOfConnections()506 int numberOfConnections() { 507 return mConnections.size(); 508 } 509 addBoundClientUid(int clientUid, String clientPackageName, long bindFlags)510 void addBoundClientUid(int clientUid, String clientPackageName, long bindFlags) { 511 mBoundClientUids.add(clientUid); 512 mApp.getWindowProcessController() 513 .addBoundClientUid(clientUid, clientPackageName, bindFlags); 514 } 515 updateBoundClientUids()516 void updateBoundClientUids() { 517 clearBoundClientUids(); 518 if (mServices.isEmpty()) { 519 return; 520 } 521 // grab a set of clientUids of all mConnections of all services 522 final ArraySet<Integer> boundClientUids = new ArraySet<>(); 523 final int serviceCount = mServices.size(); 524 WindowProcessController controller = mApp.getWindowProcessController(); 525 for (int j = 0; j < serviceCount; j++) { 526 final ArrayMap<IBinder, ArrayList<ConnectionRecord>> conns = 527 mServices.valueAt(j).getConnections(); 528 final int size = conns.size(); 529 for (int conni = 0; conni < size; conni++) { 530 ArrayList<ConnectionRecord> c = conns.valueAt(conni); 531 for (int i = 0; i < c.size(); i++) { 532 ConnectionRecord cr = c.get(i); 533 boundClientUids.add(cr.clientUid); 534 controller.addBoundClientUid(cr.clientUid, cr.clientPackageName, cr.getFlags()); 535 } 536 } 537 } 538 mBoundClientUids = boundClientUids; 539 } 540 addBoundClientUidsOfNewService(ServiceRecord sr)541 void addBoundClientUidsOfNewService(ServiceRecord sr) { 542 if (sr == null) { 543 return; 544 } 545 ArrayMap<IBinder, ArrayList<ConnectionRecord>> conns = sr.getConnections(); 546 for (int conni = conns.size() - 1; conni >= 0; conni--) { 547 ArrayList<ConnectionRecord> c = conns.valueAt(conni); 548 for (int i = 0; i < c.size(); i++) { 549 ConnectionRecord cr = c.get(i); 550 mBoundClientUids.add(cr.clientUid); 551 mApp.getWindowProcessController() 552 .addBoundClientUid(cr.clientUid, cr.clientPackageName, cr.getFlags()); 553 554 } 555 } 556 } 557 clearBoundClientUids()558 void clearBoundClientUids() { 559 mBoundClientUids.clear(); 560 mApp.getWindowProcessController().clearBoundClientUids(); 561 } 562 563 @GuardedBy("mService") updateHostingComonentTypeForBindingsLocked()564 void updateHostingComonentTypeForBindingsLocked() { 565 boolean hasBoundClient = false; 566 for (int i = numberOfRunningServices() - 1; i >= 0; i--) { 567 final ServiceRecord sr = getRunningServiceAt(i); 568 if (sr != null && !sr.getConnections().isEmpty()) { 569 hasBoundClient = true; 570 break; 571 } 572 } 573 if (hasBoundClient) { 574 mApp.mProfile.addHostingComponentType(HOSTING_COMPONENT_TYPE_BOUND_SERVICE); 575 } else { 576 mApp.mProfile.clearHostingComponentType(HOSTING_COMPONENT_TYPE_BOUND_SERVICE); 577 } 578 } 579 580 @GuardedBy("mService") incServiceCrashCountLocked(long now)581 boolean incServiceCrashCountLocked(long now) { 582 final boolean procIsBoundForeground = mApp.mState.getCurProcState() 583 == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 584 boolean tryAgain = false; 585 // Bump up the crash count of any services currently running in the proc. 586 for (int i = numberOfRunningServices() - 1; i >= 0; i--) { 587 // Any services running in the application need to be placed 588 // back in the pending list. 589 ServiceRecord sr = getRunningServiceAt(i); 590 // If the service was restarted a while ago, then reset crash count, else increment it. 591 if (now > sr.restartTime + ActivityManagerConstants.MIN_CRASH_INTERVAL) { 592 sr.crashCount = 1; 593 } else { 594 sr.crashCount++; 595 } 596 // Allow restarting for started or bound foreground services that are crashing. 597 // This includes wallpapers. 598 if (sr.crashCount < mService.mConstants.BOUND_SERVICE_MAX_CRASH_RETRY 599 && (sr.isForeground || procIsBoundForeground)) { 600 tryAgain = true; 601 } 602 } 603 return tryAgain; 604 } 605 606 @GuardedBy("mService") onCleanupApplicationRecordLocked()607 void onCleanupApplicationRecordLocked() { 608 mTreatLikeActivity = false; 609 mHasAboveClient = false; 610 setHasClientActivities(false); 611 } 612 dump(PrintWriter pw, String prefix, long nowUptime)613 void dump(PrintWriter pw, String prefix, long nowUptime) { 614 if (mHasForegroundServices || mApp.mState.getForcingToImportant() != null) { 615 pw.print(prefix); pw.print("mHasForegroundServices="); pw.print(mHasForegroundServices); 616 pw.print(" forcingToImportant="); pw.println(mApp.mState.getForcingToImportant()); 617 } 618 if (mHasTopStartedAlmostPerceptibleServices 619 || mLastTopStartedAlmostPerceptibleBindRequestUptimeMs > 0) { 620 pw.print(prefix); pw.print("mHasTopStartedAlmostPerceptibleServices="); 621 pw.print(mHasTopStartedAlmostPerceptibleServices); 622 pw.print(" mLastTopStartedAlmostPerceptibleBindRequestUptimeMs="); 623 pw.println(mLastTopStartedAlmostPerceptibleBindRequestUptimeMs); 624 } 625 if (mHasClientActivities || mHasAboveClient || mTreatLikeActivity) { 626 pw.print(prefix); pw.print("hasClientActivities="); pw.print(mHasClientActivities); 627 pw.print(" hasAboveClient="); pw.print(mHasAboveClient); 628 pw.print(" treatLikeActivity="); pw.println(mTreatLikeActivity); 629 } 630 if (mConnectionService != null || mConnectionGroup != 0) { 631 pw.print(prefix); pw.print("connectionGroup="); pw.print(mConnectionGroup); 632 pw.print(" Importance="); pw.print(mConnectionImportance); 633 pw.print(" Service="); pw.println(mConnectionService); 634 } 635 if (mAllowlistManager) { 636 pw.print(prefix); pw.print("allowlistManager="); pw.println(mAllowlistManager); 637 } 638 if (mServices.size() > 0) { 639 pw.print(prefix); pw.println("Services:"); 640 for (int i = 0, size = mServices.size(); i < size; i++) { 641 pw.print(prefix); pw.print(" - "); pw.println(mServices.valueAt(i)); 642 } 643 } 644 if (mExecutingServices.size() > 0) { 645 pw.print(prefix); pw.print("Executing Services (fg="); 646 pw.print(mExecServicesFg); pw.println(")"); 647 for (int i = 0, size = mExecutingServices.size(); i < size; i++) { 648 pw.print(prefix); pw.print(" - "); pw.println(mExecutingServices.valueAt(i)); 649 } 650 } 651 if (mConnections.size() > 0) { 652 pw.print(prefix); pw.println("mConnections:"); 653 for (int i = 0, size = mConnections.size(); i < size; i++) { 654 pw.print(prefix); pw.print(" - "); pw.println(mConnections.valueAt(i)); 655 } 656 } 657 } 658 } 659