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