• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 package com.android.server.am;
17 
18 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
19 
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.UserIdInt;
23 import android.app.ActivityManager;
24 import android.app.ActivityManagerInternal;
25 import android.content.pm.ServiceInfo;
26 import android.os.IBinder;
27 import android.os.PowerManagerInternal;
28 import android.util.Slog;
29 import android.util.SparseArray;
30 
31 import com.android.internal.annotations.GuardedBy;
32 import com.android.internal.annotations.VisibleForTesting;
33 import com.android.server.ServiceThread;
34 
35 /**
36  * ProcessStateController is responsible for maintaining state that can affect the OomAdjuster
37  * computations of a process. Any state that can affect a process's importance must be set by
38  * only ProcessStateController.
39  */
40 public class ProcessStateController {
41     public static String TAG = "ProcessStateController";
42 
43     private final OomAdjuster mOomAdjuster;
44 
45     private final GlobalState mGlobalState = new GlobalState();
46 
ProcessStateController(ActivityManagerService ams, ProcessList processList, ActiveUids activeUids, ServiceThread handlerThread, CachedAppOptimizer cachedAppOptimizer, OomAdjuster.Injector oomAdjInjector, boolean useOomAdjusterModernImpl)47     private ProcessStateController(ActivityManagerService ams, ProcessList processList,
48             ActiveUids activeUids, ServiceThread handlerThread,
49             CachedAppOptimizer cachedAppOptimizer, OomAdjuster.Injector oomAdjInjector,
50             boolean useOomAdjusterModernImpl) {
51         mOomAdjuster = useOomAdjusterModernImpl
52                 ? new OomAdjusterModernImpl(ams, processList, activeUids, handlerThread,
53                 mGlobalState, cachedAppOptimizer, oomAdjInjector)
54                 : new OomAdjuster(ams, processList, activeUids, handlerThread, mGlobalState,
55                         cachedAppOptimizer, oomAdjInjector);
56     }
57 
58     /**
59      * Get the instance of OomAdjuster that ProcessStateController is using.
60      * Must only be interacted with while holding the ActivityManagerService lock.
61      */
getOomAdjuster()62     public OomAdjuster getOomAdjuster() {
63         return mOomAdjuster;
64     }
65 
66     /**
67      * Add a process to evaluated the next time an update is run.
68      */
enqueueUpdateTarget(@onNull ProcessRecord proc)69     public void enqueueUpdateTarget(@NonNull ProcessRecord proc) {
70         mOomAdjuster.enqueueOomAdjTargetLocked(proc);
71     }
72 
73     /**
74      * Remove a process that was added by {@link #enqueueUpdateTarget}.
75      */
removeUpdateTarget(@onNull ProcessRecord proc, boolean procDied)76     public void removeUpdateTarget(@NonNull ProcessRecord proc, boolean procDied) {
77         mOomAdjuster.removeOomAdjTargetLocked(proc, procDied);
78     }
79 
80     /**
81      * Trigger an update on a single process (and any processes that have been enqueued with
82      * {@link #enqueueUpdateTarget}).
83      */
runUpdate(@onNull ProcessRecord proc, @ActivityManagerInternal.OomAdjReason int oomAdjReason)84     public boolean runUpdate(@NonNull ProcessRecord proc,
85             @ActivityManagerInternal.OomAdjReason int oomAdjReason) {
86         return mOomAdjuster.updateOomAdjLocked(proc, oomAdjReason);
87     }
88 
89     /**
90      * Trigger an update on all processes that have been enqueued with {@link #enqueueUpdateTarget}.
91      */
runPendingUpdate(@ctivityManagerInternal.OomAdjReason int oomAdjReason)92     public void runPendingUpdate(@ActivityManagerInternal.OomAdjReason int oomAdjReason) {
93         mOomAdjuster.updateOomAdjPendingTargetsLocked(oomAdjReason);
94     }
95 
96     /**
97      * Trigger an update on all processes.
98      */
runFullUpdate(@ctivityManagerInternal.OomAdjReason int oomAdjReason)99     public void runFullUpdate(@ActivityManagerInternal.OomAdjReason int oomAdjReason) {
100         mOomAdjuster.updateOomAdjLocked(oomAdjReason);
101     }
102 
103     /**
104      * Trigger an update on any processes that have been marked for follow up during a previous
105      * update.
106      */
runFollowUpUpdate()107     public void runFollowUpUpdate() {
108         mOomAdjuster.updateOomAdjFollowUpTargetsLocked();
109     }
110 
111     private static class GlobalState implements OomAdjuster.GlobalState {
112         public boolean isAwake = true;
113         // TODO(b/369300367): Maintaining global state for backup processes is a bit convoluted.
114         //  ideally the state gets migrated to ProcessStateRecord.
115         public final SparseArray<ProcessRecord> backupTargets = new SparseArray<>();
116         public boolean isLastMemoryLevelNormal = true;
117 
isAwake()118         public boolean isAwake() {
119             return isAwake;
120         }
121 
getBackupTarget(@serIdInt int userId)122         public ProcessRecord getBackupTarget(@UserIdInt int userId) {
123             return backupTargets.get(userId);
124         }
125 
isLastMemoryLevelNormal()126         public boolean isLastMemoryLevelNormal() {
127             return isLastMemoryLevelNormal;
128         }
129     }
130 
131     /*************************** Global State Events ***************************/
132     /**
133      * Set which process state Top processes should get.
134      */
setTopProcessState(@ctivityManager.ProcessState int procState)135     public void setTopProcessState(@ActivityManager.ProcessState int procState) {
136         // TODO(b/302575389): Migrate state pulled from ATMS to a pushed model
137         throw new UnsupportedOperationException("Not implemented yet");
138     }
139 
140     /**
141      * Set whether to give Top processes the Top sched group.
142      */
setUseTopSchedGroupForTopProcess(boolean useTopSchedGroup)143     public void setUseTopSchedGroupForTopProcess(boolean useTopSchedGroup) {
144         // TODO(b/302575389): Migrate state pulled from ATMS to a pushed model
145         throw new UnsupportedOperationException("Not implemented yet");
146     }
147 
148     /**
149      * Set the Top process.
150      */
setTopApp(@ullable ProcessRecord proc)151     public void setTopApp(@Nullable ProcessRecord proc) {
152         // TODO(b/302575389): Migrate state pulled from ATMS to a pushed model
153         throw new UnsupportedOperationException("Not implemented yet");
154     }
155 
156     /**
157      * Set which process is considered the Home process, if any.
158      */
setHomeProcess(@ullable ProcessRecord proc)159     public void setHomeProcess(@Nullable ProcessRecord proc) {
160         // TODO(b/302575389): Migrate state pulled from ATMS to a pushed model
161         throw new UnsupportedOperationException("Not implemented yet");
162     }
163 
164     /**
165      * Set which process is considered the Heavy Weight process, if any.
166      */
setHeavyWeightProcess(@ullable ProcessRecord proc)167     public void setHeavyWeightProcess(@Nullable ProcessRecord proc) {
168         // TODO(b/302575389): Migrate state pulled from ATMS to a pushed model
169         throw new UnsupportedOperationException("Not implemented yet");
170     }
171 
172     /**
173      * Set which process is showing UI while the screen is off, if any.
174      */
setVisibleDozeUiProcess(@ullable ProcessRecord proc)175     public void setVisibleDozeUiProcess(@Nullable ProcessRecord proc) {
176         // TODO(b/302575389): Migrate state pulled from ATMS to a pushed model
177         throw new UnsupportedOperationException("Not implemented yet");
178     }
179 
180     /**
181      * Set which process is considered the Previous process, if any.
182      */
setPreviousProcess(@ullable ProcessRecord proc)183     public void setPreviousProcess(@Nullable ProcessRecord proc) {
184         // TODO(b/302575389): Migrate state pulled from ATMS to a pushed model
185         throw new UnsupportedOperationException("Not implemented yet");
186     }
187 
188     /**
189      * Set what wakefulness state the screen is in.
190      */
setWakefulness(int wakefulness)191     public void setWakefulness(int wakefulness) {
192         mGlobalState.isAwake = (wakefulness == PowerManagerInternal.WAKEFULNESS_AWAKE);
193         mOomAdjuster.onWakefulnessChanged(wakefulness);
194     }
195 
196     /**
197      * Set for a given user what process is currently running a backup, if any.
198      */
setBackupTarget(@onNull ProcessRecord proc, @UserIdInt int userId)199     public void setBackupTarget(@NonNull ProcessRecord proc, @UserIdInt int userId) {
200         mGlobalState.backupTargets.put(userId, proc);
201     }
202 
203     /**
204      * No longer consider any process running a backup for a given user.
205      */
stopBackupTarget(@serIdInt int userId)206     public void stopBackupTarget(@UserIdInt int userId) {
207         mGlobalState.backupTargets.delete(userId);
208     }
209 
210     /**
211      * Set whether the last known memory level is normal.
212      */
setIsLastMemoryLevelNormal(boolean isMemoryNormal)213     public void setIsLastMemoryLevelNormal(boolean isMemoryNormal) {
214         mGlobalState.isLastMemoryLevelNormal = isMemoryNormal;
215     }
216 
217     /***************************** UID State Events ****************************/
218     /**
219      * Set a UID as temp allowlisted.
220      */
setUidTempAllowlistStateLSP(int uid, boolean allowList)221     public void setUidTempAllowlistStateLSP(int uid, boolean allowList) {
222         mOomAdjuster.setUidTempAllowlistStateLSP(uid, allowList);
223     }
224 
225     /*********************** Process Miscellaneous Events **********************/
226     /**
227      * Set the maximum adj score a process can be assigned.
228      */
setMaxAdj(@onNull ProcessRecord proc, int adj)229     public void setMaxAdj(@NonNull ProcessRecord proc, int adj) {
230         proc.mState.setMaxAdj(adj);
231     }
232 
233     /**
234      * Initialize a process that is being attached.
235      */
236     @GuardedBy({"mService", "mProcLock"})
setAttachingProcessStatesLSP(@onNull ProcessRecord proc)237     public void setAttachingProcessStatesLSP(@NonNull ProcessRecord proc) {
238         mOomAdjuster.setAttachingProcessStatesLSP(proc);
239     }
240 
241     /**
242      * Note whether a process is pending attach or not.
243      */
setPendingFinishAttach(@onNull ProcessRecord proc, boolean pendingFinishAttach)244     public void setPendingFinishAttach(@NonNull ProcessRecord proc, boolean pendingFinishAttach) {
245         proc.setPendingFinishAttach(pendingFinishAttach);
246     }
247 
248     /**
249      * Sets an active instrumentation running within the given process.
250      */
setActiveInstrumentation(@onNull ProcessRecord proc, ActiveInstrumentation activeInstrumentation)251     public void setActiveInstrumentation(@NonNull ProcessRecord proc,
252             ActiveInstrumentation activeInstrumentation) {
253         proc.setActiveInstrumentation(activeInstrumentation);
254     }
255 
256     /********************* Process Visibility State Events *********************/
257     /**
258      * Note whether a process has Top UI or not.
259      *
260      * @return true if the state changed, otherwise returns false.
261      */
setHasTopUi(@onNull ProcessRecord proc, boolean hasTopUi)262     public boolean setHasTopUi(@NonNull ProcessRecord proc, boolean hasTopUi) {
263         if (proc.mState.hasTopUi() == hasTopUi) return false;
264         if (DEBUG_OOM_ADJ) {
265             Slog.d(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + proc.getPid());
266         }
267         proc.mState.setHasTopUi(hasTopUi);
268         return true;
269     }
270 
271     /**
272      * Note whether a process is displaying Overlay UI or not.
273      *
274      * @return true if the state changed, otherwise returns false.
275      */
setHasOverlayUi(@onNull ProcessRecord proc, boolean hasOverlayUi)276     public boolean setHasOverlayUi(@NonNull ProcessRecord proc, boolean hasOverlayUi) {
277         if (proc.mState.hasOverlayUi() == hasOverlayUi) return false;
278         proc.mState.setHasOverlayUi(hasOverlayUi);
279         return true;
280     }
281 
282 
283     /**
284      * Note whether a process is running a remote animation.
285      *
286      * @return true if the state changed, otherwise returns false.
287      */
setRunningRemoteAnimation(@onNull ProcessRecord proc, boolean runningRemoteAnimation)288     public boolean setRunningRemoteAnimation(@NonNull ProcessRecord proc,
289             boolean runningRemoteAnimation) {
290         if (proc.mState.isRunningRemoteAnimation() == runningRemoteAnimation) return false;
291         if (DEBUG_OOM_ADJ) {
292             Slog.i(TAG, "Setting runningRemoteAnimation=" + runningRemoteAnimation
293                     + " for pid=" + proc.getPid());
294         }
295         proc.mState.setRunningRemoteAnimation(runningRemoteAnimation);
296         return true;
297     }
298 
299     /**
300      * Note that the process is showing a toast.
301      */
setForcingToImportant(@onNull ProcessRecord proc, @Nullable Object forcingToImportant)302     public void setForcingToImportant(@NonNull ProcessRecord proc,
303             @Nullable Object forcingToImportant) {
304         if (proc.mState.getForcingToImportant() == forcingToImportant) return;
305         proc.mState.setForcingToImportant(forcingToImportant);
306     }
307 
308     /**
309      * Note that the process has shown UI at some point in its life.
310      */
setHasShownUi(@onNull ProcessRecord proc, boolean hasShownUi)311     public void setHasShownUi(@NonNull ProcessRecord proc, boolean hasShownUi) {
312         // This arguably should be turned into an internal state of OomAdjuster.
313         if (proc.mState.hasShownUi() == hasShownUi) return;
314         proc.mState.setHasShownUi(hasShownUi);
315     }
316 
317     /**
318      * Note whether the process has an activity or not.
319      */
setHasActivity(@onNull ProcessRecord proc, boolean hasActivity)320     public void setHasActivity(@NonNull ProcessRecord proc, boolean hasActivity) {
321         // TODO(b/302575389): Migrate state pulled from ATMS to a pushed model
322         // Possibly not needed, maybe can use ActivityStateFlags.
323         throw new UnsupportedOperationException("Not implemented yet");
324     }
325 
326     /**
327      * Note whether the process has a visibly activity or not.
328      */
setHasVisibleActivity(@onNull ProcessRecord proc, boolean hasVisibleActivity)329     public void setHasVisibleActivity(@NonNull ProcessRecord proc, boolean hasVisibleActivity) {
330         // TODO(b/302575389): Migrate state pulled from ATMS to a pushed model
331         // maybe used ActivityStateFlags instead.
332         throw new UnsupportedOperationException("Not implemented yet");
333     }
334 
335     /**
336      * Set the Activity State Flags for a process.
337      */
setActivityStateFlags(@onNull ProcessRecord proc, int flags)338     public void setActivityStateFlags(@NonNull ProcessRecord proc, int flags) {
339         // TODO(b/302575389): Migrate state pulled from ATMS to a pushed model
340         throw new UnsupportedOperationException("Not implemented yet");
341     }
342 
343     /********************** Content Provider State Events **********************/
344     /**
345      * Note that a process is hosting a content provider.
346      */
addPublishedProvider(@onNull ProcessRecord proc, String name, ContentProviderRecord cpr)347     public boolean addPublishedProvider(@NonNull ProcessRecord proc, String name,
348             ContentProviderRecord cpr) {
349         final ProcessProviderRecord providers = proc.mProviders;
350         if (providers.hasProvider(name)) return false;
351         providers.installProvider(name, cpr);
352         return true;
353     }
354 
355     /**
356      * Remove a published content provider from a process.
357      */
removePublishedProvider(@onNull ProcessRecord proc, String name)358     public void removePublishedProvider(@NonNull ProcessRecord proc, String name) {
359         final ProcessProviderRecord providers = proc.mProviders;
360         providers.removeProvider(name);
361     }
362 
363     /**
364      * Note that a content provider has an external client.
365      */
addExternalProviderClient(@onNull ContentProviderRecord cpr, IBinder externalProcessToken, int callingUid, String callingTag)366     public void addExternalProviderClient(@NonNull ContentProviderRecord cpr,
367             IBinder externalProcessToken, int callingUid, String callingTag) {
368         cpr.addExternalProcessHandleLocked(externalProcessToken, callingUid, callingTag);
369     }
370 
371     /**
372      * Remove an external client from a conetnt provider.
373      */
removeExternalProviderClient(@onNull ContentProviderRecord cpr, IBinder externalProcessToken)374     public boolean removeExternalProviderClient(@NonNull ContentProviderRecord cpr,
375             IBinder externalProcessToken) {
376         return cpr.removeExternalProcessHandleLocked(externalProcessToken);
377     }
378 
379     /**
380      * Note the time a process is no longer hosting any content providers.
381      */
setLastProviderTime(@onNull ProcessRecord proc, long uptimeMs)382     public void setLastProviderTime(@NonNull ProcessRecord proc, long uptimeMs) {
383         proc.mProviders.setLastProviderTime(uptimeMs);
384     }
385 
386     /**
387      * Note that a process has connected to a content provider.
388      */
addProviderConnection(@onNull ProcessRecord client, ContentProviderConnection cpc)389     public void addProviderConnection(@NonNull ProcessRecord client,
390             ContentProviderConnection cpc) {
391         client.mProviders.addProviderConnection(cpc);
392     }
393 
394     /**
395      * Note that a process is no longer connected to a content provider.
396      */
removeProviderConnection(@onNull ProcessRecord client, ContentProviderConnection cpc)397     public void removeProviderConnection(@NonNull ProcessRecord client,
398             ContentProviderConnection cpc) {
399         client.mProviders.removeProviderConnection(cpc);
400     }
401 
402     /*************************** Service State Events **************************/
403     /**
404      * Note that a process has started hosting a service.
405      */
startService(@onNull ProcessServiceRecord psr, ServiceRecord sr)406     public boolean startService(@NonNull ProcessServiceRecord psr, ServiceRecord sr) {
407         return psr.startService(sr);
408     }
409 
410     /**
411      * Note that a process has stopped hosting a service.
412      */
stopService(@onNull ProcessServiceRecord psr, ServiceRecord sr)413     public boolean stopService(@NonNull ProcessServiceRecord psr, ServiceRecord sr) {
414         return psr.stopService(sr);
415     }
416 
417     /**
418      * Remove all services that the process is hosting.
419      */
stopAllServices(@onNull ProcessServiceRecord psr)420     public void stopAllServices(@NonNull ProcessServiceRecord psr) {
421         psr.stopAllServices();
422     }
423 
424     /**
425      * Note that a process's service has started executing.
426      */
startExecutingService(@onNull ProcessServiceRecord psr, ServiceRecord sr)427     public void startExecutingService(@NonNull ProcessServiceRecord psr, ServiceRecord sr) {
428         psr.startExecutingService(sr);
429     }
430 
431     /**
432      * Note that a process's service has stopped executing.
433      */
stopExecutingService(@onNull ProcessServiceRecord psr, ServiceRecord sr)434     public void stopExecutingService(@NonNull ProcessServiceRecord psr, ServiceRecord sr) {
435         psr.stopExecutingService(sr);
436     }
437 
438     /**
439      * Note all executing services a process has has stopped.
440      */
stopAllExecutingServices(@onNull ProcessServiceRecord psr)441     public void stopAllExecutingServices(@NonNull ProcessServiceRecord psr) {
442         psr.stopAllExecutingServices();
443     }
444 
445     /**
446      * Note that process has bound to a service.
447      */
addConnection(@onNull ProcessServiceRecord psr, ConnectionRecord cr)448     public void addConnection(@NonNull ProcessServiceRecord psr, ConnectionRecord cr) {
449         psr.addConnection(cr);
450     }
451 
452     /**
453      * Note that process has unbound from a service.
454      */
removeConnection(@onNull ProcessServiceRecord psr, ConnectionRecord cr)455     public void removeConnection(@NonNull ProcessServiceRecord psr, ConnectionRecord cr) {
456         psr.removeConnection(cr);
457     }
458 
459     /**
460      * Remove all bindings a process has to services.
461      */
removeAllConnections(@onNull ProcessServiceRecord psr)462     public void removeAllConnections(@NonNull ProcessServiceRecord psr) {
463         psr.removeAllConnections();
464         psr.removeAllSdkSandboxConnections();
465     }
466 
467     /**
468      * Note whether an executing service should be considered in the foreground or not.
469      */
setExecServicesFg(@onNull ProcessServiceRecord psr, boolean execServicesFg)470     public void setExecServicesFg(@NonNull ProcessServiceRecord psr, boolean execServicesFg) {
471         psr.setExecServicesFg(execServicesFg);
472     }
473 
474     /**
475      * Note whether a service is in the foreground or not and what type of FGS, if so.
476      */
setHasForegroundServices(@onNull ProcessServiceRecord psr, boolean hasForegroundServices, int fgServiceTypes, boolean hasTypeNoneFgs)477     public void setHasForegroundServices(@NonNull ProcessServiceRecord psr,
478             boolean hasForegroundServices,
479             int fgServiceTypes, boolean hasTypeNoneFgs) {
480         psr.setHasForegroundServices(hasForegroundServices, fgServiceTypes, hasTypeNoneFgs);
481     }
482 
483     /**
484      * Note whether a service has a client activity or not.
485      */
setHasClientActivities(@onNull ProcessServiceRecord psr, boolean hasClientActivities)486     public void setHasClientActivities(@NonNull ProcessServiceRecord psr,
487             boolean hasClientActivities) {
488         psr.setHasClientActivities(hasClientActivities);
489     }
490 
491     /**
492      * Note whether a service should be treated like an activity or not.
493      */
setTreatLikeActivity(@onNull ProcessServiceRecord psr, boolean treatLikeActivity)494     public void setTreatLikeActivity(@NonNull ProcessServiceRecord psr, boolean treatLikeActivity) {
495         psr.setTreatLikeActivity(treatLikeActivity);
496     }
497 
498     /**
499      * Note whether a process has bound to a service with
500      * {@link android.content.Context.BIND_ABOVE_CLIENT} or not.
501      */
setHasAboveClient(@onNull ProcessServiceRecord psr, boolean hasAboveClient)502     public void setHasAboveClient(@NonNull ProcessServiceRecord psr, boolean hasAboveClient) {
503         psr.setHasAboveClient(hasAboveClient);
504     }
505 
506     /**
507      * Recompute whether a process has bound to a service with
508      * {@link android.content.Context.BIND_ABOVE_CLIENT} or not.
509      */
updateHasAboveClientLocked(@onNull ProcessServiceRecord psr)510     public void updateHasAboveClientLocked(@NonNull ProcessServiceRecord psr) {
511         psr.updateHasAboveClientLocked();
512     }
513 
514     /**
515      * Cleanup a process's state.
516      */
onCleanupApplicationRecord(@onNull ProcessServiceRecord psr)517     public void onCleanupApplicationRecord(@NonNull ProcessServiceRecord psr) {
518         psr.onCleanupApplicationRecordLocked();
519     }
520 
521     /**
522      * Set which process is hosting a service.
523      */
setHostProcess(@onNull ServiceRecord sr, @Nullable ProcessRecord host)524     public void setHostProcess(@NonNull ServiceRecord sr, @Nullable ProcessRecord host) {
525         sr.app = host;
526     }
527 
528     /**
529      * Note whether a service is a Foreground Service or not
530      */
setIsForegroundService(@onNull ServiceRecord sr, boolean isFgs)531     public void setIsForegroundService(@NonNull ServiceRecord sr, boolean isFgs) {
532         sr.isForeground = isFgs;
533     }
534 
535     /**
536      * Note the Foreground Service type of a service.
537      */
setForegroundServiceType(@onNull ServiceRecord sr, @ServiceInfo.ForegroundServiceType int fgsType)538     public void setForegroundServiceType(@NonNull ServiceRecord sr,
539             @ServiceInfo.ForegroundServiceType int fgsType) {
540         sr.foregroundServiceType = fgsType;
541     }
542 
543     /**
544      * Note the start time of a short foreground service.
545      */
setShortFgsInfo(@onNull ServiceRecord sr, long uptimeNow)546     public void setShortFgsInfo(@NonNull ServiceRecord sr, long uptimeNow) {
547         sr.setShortFgsInfo(uptimeNow);
548     }
549 
550     /**
551      * Note that a short foreground service has stopped.
552      */
clearShortFgsInfo(@onNull ServiceRecord sr)553     public void clearShortFgsInfo(@NonNull ServiceRecord sr) {
554         sr.clearShortFgsInfo();
555     }
556 
557     /**
558      * Note the last time a service was active.
559      */
setServiceLastActivityTime(@onNull ServiceRecord sr, long lastActivityUpdateMs)560     public void setServiceLastActivityTime(@NonNull ServiceRecord sr, long lastActivityUpdateMs) {
561         sr.lastActivity = lastActivityUpdateMs;
562     }
563 
564     /**
565      * Note that a service start was requested.
566      */
setStartRequested(@onNull ServiceRecord sr, boolean startRequested)567     public void setStartRequested(@NonNull ServiceRecord sr, boolean startRequested) {
568         sr.startRequested = startRequested;
569     }
570 
571     /**
572      * Note the last time the service was bound by a Top process with
573      * {@link android.content.Context.BIND_ALMOST_PERCEPTIBLE}
574      */
setLastTopAlmostPerceptibleBindRequest(@onNull ServiceRecord sr, long lastTopAlmostPerceptibleBindRequestUptimeMs)575     public void setLastTopAlmostPerceptibleBindRequest(@NonNull ServiceRecord sr,
576             long lastTopAlmostPerceptibleBindRequestUptimeMs) {
577         sr.lastTopAlmostPerceptibleBindRequestUptimeMs =
578                 lastTopAlmostPerceptibleBindRequestUptimeMs;
579     }
580 
581     /**
582      * Recompute whether a process has bound to a service with
583      * {@link android.content.Context.BIND_ALMOST_PERCEPTIBLE} or not.
584      */
updateHasTopStartedAlmostPerceptibleServices(@onNull ProcessServiceRecord psr)585     public void updateHasTopStartedAlmostPerceptibleServices(@NonNull ProcessServiceRecord psr) {
586         psr.updateHasTopStartedAlmostPerceptibleServices();
587     }
588 
589     /************************ Broadcast Receiver State Events **************************/
590     /**
591      * Set what sched group to grant a process due to running a broadcast.
592      * {@link ProcessList.SCHED_GROUP_UNDEFINED} means the process is not running a broadcast.
593      */
setBroadcastSchedGroup(@onNull ProcessRecord proc, int schedGroup)594     public void setBroadcastSchedGroup(@NonNull ProcessRecord proc, int schedGroup) {
595         // TODO(b/302575389): Migrate state pulled from BroadcastQueue to a pushed model
596         throw new UnsupportedOperationException("Not implemented yet");
597     }
598 
599     /**
600      * Note that the process has started processing a broadcast receiver.
601      */
incrementCurReceivers(@onNull ProcessRecord app)602     public boolean incrementCurReceivers(@NonNull ProcessRecord app) {
603         // TODO(b/302575389): Migrate state pulled from ATMS to a pushed model
604         // maybe used ActivityStateFlags instead.
605         throw new UnsupportedOperationException("Not implemented yet");
606     }
607 
608     /**
609      * Note that the process has finished processing a broadcast receiver.
610      */
decrementCurReceivers(@onNull ProcessRecord app)611     public boolean decrementCurReceivers(@NonNull ProcessRecord app) {
612         // TODO(b/302575389): Migrate state pulled from ATMS to a pushed model
613         // maybe used ActivityStateFlags instead.
614         throw new UnsupportedOperationException("Not implemented yet");
615     }
616 
617     /**
618      * Builder for ProcessStateController.
619      */
620     public static class Builder {
621         private final ActivityManagerService mAms;
622         private final ProcessList mProcessList;
623         private final ActiveUids mActiveUids;
624 
625         private ServiceThread mHandlerThread = null;
626         private CachedAppOptimizer mCachedAppOptimizer = null;
627         private OomAdjuster.Injector mOomAdjInjector = null;
628         private boolean mUseOomAdjusterModernImpl = false;
629 
Builder(ActivityManagerService ams, ProcessList processList, ActiveUids activeUids)630         public Builder(ActivityManagerService ams, ProcessList processList, ActiveUids activeUids) {
631             mAms = ams;
632             mProcessList = processList;
633             mActiveUids = activeUids;
634         }
635 
636         /**
637          * Build the ProcessStateController object.
638          */
build()639         public ProcessStateController build() {
640             if (mHandlerThread == null) {
641                 mHandlerThread = OomAdjuster.createAdjusterThread();
642             }
643             if (mCachedAppOptimizer == null) {
644                 mCachedAppOptimizer = new CachedAppOptimizer(mAms);
645             }
646             if (mOomAdjInjector == null) {
647                 mOomAdjInjector = new OomAdjuster.Injector();
648             }
649             return new ProcessStateController(mAms, mProcessList, mActiveUids, mHandlerThread,
650                     mCachedAppOptimizer, mOomAdjInjector, mUseOomAdjusterModernImpl);
651         }
652 
653         /**
654          * For Testing Purposes. Set what thread OomAdjuster will offload tasks on to.
655          */
656         @VisibleForTesting
setHandlerThread(ServiceThread handlerThread)657         public Builder setHandlerThread(ServiceThread handlerThread) {
658             mHandlerThread = handlerThread;
659             return this;
660         }
661 
662         /**
663          * For Testing Purposes. Set the CachedAppOptimzer used by OomAdjuster.
664          */
665         @VisibleForTesting
setCachedAppOptimizer(CachedAppOptimizer cachedAppOptimizer)666         public Builder setCachedAppOptimizer(CachedAppOptimizer cachedAppOptimizer) {
667             mCachedAppOptimizer = cachedAppOptimizer;
668             return this;
669         }
670 
671         /**
672          * For Testing Purposes. Set an injector for OomAdjuster.
673          */
674         @VisibleForTesting
setOomAdjusterInjector(OomAdjuster.Injector injector)675         public Builder setOomAdjusterInjector(OomAdjuster.Injector injector) {
676             mOomAdjInjector = injector;
677             return this;
678         }
679 
680         /**
681          * Set which implementation of OomAdjuster to use.
682          */
useModernOomAdjuster(boolean use)683         public Builder useModernOomAdjuster(boolean use) {
684             mUseOomAdjusterModernImpl = use;
685             return this;
686         }
687     }
688 }
689