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