1 /* 2 * Copyright (C) 2019 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.ActivityManager.PROCESS_CAPABILITY_ALL; 20 import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL_IMPLICIT; 21 import static android.app.ActivityManager.PROCESS_CAPABILITY_BFSL; 22 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL; 23 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA; 24 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION; 25 import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE; 26 import static android.app.ActivityManager.PROCESS_CAPABILITY_NONE; 27 import static android.app.ActivityManager.PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK; 28 import static android.app.ActivityManager.PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK; 29 import static android.app.ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 30 import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP; 31 import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY; 32 import static android.app.ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 33 import static android.app.ActivityManager.PROCESS_STATE_CACHED_EMPTY; 34 import static android.app.ActivityManager.PROCESS_STATE_CACHED_RECENT; 35 import static android.app.ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE; 36 import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND; 37 import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND; 38 import static android.app.ActivityManager.PROCESS_STATE_LAST_ACTIVITY; 39 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; 40 import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT; 41 import static android.app.ActivityManager.PROCESS_STATE_PERSISTENT_UI; 42 import static android.app.ActivityManager.PROCESS_STATE_SERVICE; 43 import static android.app.ActivityManager.PROCESS_STATE_TOP; 44 import static android.app.ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND; 45 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_ACTIVITY; 46 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_ALLOWLIST; 47 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_BACKUP; 48 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_BIND_SERVICE; 49 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_COMPONENT_DISABLED; 50 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_EXECUTING_SERVICE; 51 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_FINISH_RECEIVER; 52 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_FOLLOW_UP; 53 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_GET_PROVIDER; 54 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_NONE; 55 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_PROCESS_BEGIN; 56 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_PROCESS_END; 57 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_REMOVE_PROVIDER; 58 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_REMOVE_TASK; 59 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_RESTRICTION_CHANGE; 60 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_SHELL; 61 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_SHORT_FGS_TIMEOUT; 62 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_START_RECEIVER; 63 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_START_SERVICE; 64 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_STOP_SERVICE; 65 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_SYSTEM_INIT; 66 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_UID_IDLE; 67 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_UI_VISIBILITY; 68 import static android.app.ActivityManagerInternal.OOM_ADJ_REASON_UNBIND_SERVICE; 69 import static android.content.Context.BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE; 70 import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA; 71 import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_LOCATION; 72 import static android.content.pm.ServiceInfo.FOREGROUND_SERVICE_TYPE_MICROPHONE; 73 import static android.media.audio.Flags.roForegroundAudioControl; 74 import static android.os.Process.THREAD_GROUP_BACKGROUND; 75 import static android.os.Process.THREAD_GROUP_DEFAULT; 76 import static android.os.Process.THREAD_GROUP_RESTRICTED; 77 import static android.os.Process.THREAD_GROUP_TOP_APP; 78 import static android.os.Process.THREAD_PRIORITY_DISPLAY; 79 import static android.os.Process.THREAD_PRIORITY_TOP_APP_BOOST; 80 import static android.os.Process.setProcessGroup; 81 import static android.os.Process.setThreadPriority; 82 83 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL; 84 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP; 85 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU; 86 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ; 87 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ_REASON; 88 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS; 89 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS; 90 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS; 91 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS; 92 import static com.android.server.am.ActivityManagerService.DISPATCH_OOM_ADJ_OBSERVER_MSG; 93 import static com.android.server.am.ActivityManagerService.FOLLOW_UP_OOMADJUSTER_UPDATE_MSG; 94 import static com.android.server.am.ActivityManagerService.IDLE_UIDS_MSG; 95 import static com.android.server.am.ActivityManagerService.TAG_BACKUP; 96 import static com.android.server.am.ActivityManagerService.TAG_LRU; 97 import static com.android.server.am.ActivityManagerService.TAG_OOM_ADJ; 98 import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS; 99 import static com.android.server.am.AppProfiler.TAG_PSS; 100 import static com.android.server.am.PlatformCompatCache.CACHED_COMPAT_CHANGE_CAMERA_MICROPHONE_CAPABILITY; 101 import static com.android.server.am.PlatformCompatCache.CACHED_COMPAT_CHANGE_PROCESS_CAPABILITY; 102 import static com.android.server.am.PlatformCompatCache.CACHED_COMPAT_CHANGE_USE_SHORT_FGS_USAGE_INTERACTION_TIME; 103 import static com.android.server.am.ProcessList.BACKUP_APP_ADJ; 104 import static com.android.server.am.ProcessList.CACHED_APP_IMPORTANCE_LEVELS; 105 import static com.android.server.am.ProcessList.CACHED_APP_MAX_ADJ; 106 import static com.android.server.am.ProcessList.CACHED_APP_MIN_ADJ; 107 import static com.android.server.am.ProcessList.FOREGROUND_APP_ADJ; 108 import static com.android.server.am.ProcessList.FREEZER_CUTOFF_ADJ; 109 import static com.android.server.am.ProcessList.HEAVY_WEIGHT_APP_ADJ; 110 import static com.android.server.am.ProcessList.HOME_APP_ADJ; 111 import static com.android.server.am.ProcessList.INVALID_ADJ; 112 import static com.android.server.am.ProcessList.PERCEPTIBLE_APP_ADJ; 113 import static com.android.server.am.ProcessList.PERCEPTIBLE_LOW_APP_ADJ; 114 import static com.android.server.am.ProcessList.PERCEPTIBLE_MEDIUM_APP_ADJ; 115 import static com.android.server.am.ProcessList.PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ; 116 import static com.android.server.am.ProcessList.PERSISTENT_SERVICE_ADJ; 117 import static com.android.server.am.ProcessList.PREVIOUS_APP_ADJ; 118 import static com.android.server.am.ProcessList.SCHED_GROUP_BACKGROUND; 119 import static com.android.server.am.ProcessList.SCHED_GROUP_DEFAULT; 120 import static com.android.server.am.ProcessList.SCHED_GROUP_RESTRICTED; 121 import static com.android.server.am.ProcessList.SCHED_GROUP_TOP_APP; 122 import static com.android.server.am.ProcessList.SCHED_GROUP_TOP_APP_BOUND; 123 import static com.android.server.am.ProcessList.SERVICE_ADJ; 124 import static com.android.server.am.ProcessList.SERVICE_B_ADJ; 125 import static com.android.server.am.ProcessList.TAG_PROCESS_OBSERVERS; 126 import static com.android.server.am.ProcessList.UNKNOWN_ADJ; 127 import static com.android.server.am.ProcessList.VISIBLE_APP_ADJ; 128 import static com.android.server.wm.ActivityTaskManagerDebugConfig.DEBUG_SWITCH; 129 130 import android.annotation.NonNull; 131 import android.annotation.Nullable; 132 import android.app.ActivityManager; 133 import android.app.ActivityManagerInternal.OomAdjReason; 134 import android.app.ActivityThread; 135 import android.app.AppProtoEnums; 136 import android.app.ApplicationExitInfo; 137 import android.app.usage.UsageEvents; 138 import android.compat.annotation.ChangeId; 139 import android.compat.annotation.EnabledAfter; 140 import android.compat.annotation.EnabledSince; 141 import android.content.BroadcastReceiver; 142 import android.content.ComponentName; 143 import android.content.Context; 144 import android.content.Intent; 145 import android.content.IntentFilter; 146 import android.content.pm.ApplicationInfo; 147 import android.content.pm.ServiceInfo; 148 import android.net.NetworkPolicyManager; 149 import android.os.Handler; 150 import android.os.IBinder; 151 import android.os.PowerManagerInternal; 152 import android.os.Process; 153 import android.os.RemoteException; 154 import android.os.SystemClock; 155 import android.os.Trace; 156 import android.util.ArrayMap; 157 import android.util.ArraySet; 158 import android.util.Slog; 159 import android.util.proto.ProtoOutputStream; 160 161 import com.android.internal.annotations.CompositeRWLock; 162 import com.android.internal.annotations.GuardedBy; 163 import com.android.internal.annotations.VisibleForTesting; 164 import com.android.server.ServiceThread; 165 import com.android.server.am.PlatformCompatCache.CachedCompatChangeId; 166 import com.android.server.wm.ActivityServiceConnectionsHolder; 167 import com.android.server.wm.WindowProcessController; 168 169 import java.io.PrintWriter; 170 import java.util.ArrayDeque; 171 import java.util.ArrayList; 172 import java.util.Arrays; 173 import java.util.List; 174 175 /** 176 * All of the code required to compute proc states and oom_adj values. 177 */ 178 public class OomAdjuster { 179 static final String TAG = "OomAdjuster"; 180 oomAdjReasonToProto(@omAdjReason int oomReason)181 public static final int oomAdjReasonToProto(@OomAdjReason int oomReason) { 182 switch (oomReason) { 183 case OOM_ADJ_REASON_NONE: 184 return AppProtoEnums.OOM_ADJ_REASON_NONE; 185 case OOM_ADJ_REASON_ACTIVITY: 186 return AppProtoEnums.OOM_ADJ_REASON_ACTIVITY; 187 case OOM_ADJ_REASON_FINISH_RECEIVER: 188 return AppProtoEnums.OOM_ADJ_REASON_FINISH_RECEIVER; 189 case OOM_ADJ_REASON_START_RECEIVER: 190 return AppProtoEnums.OOM_ADJ_REASON_START_RECEIVER; 191 case OOM_ADJ_REASON_BIND_SERVICE: 192 return AppProtoEnums.OOM_ADJ_REASON_BIND_SERVICE; 193 case OOM_ADJ_REASON_UNBIND_SERVICE: 194 return AppProtoEnums.OOM_ADJ_REASON_UNBIND_SERVICE; 195 case OOM_ADJ_REASON_START_SERVICE: 196 return AppProtoEnums.OOM_ADJ_REASON_START_SERVICE; 197 case OOM_ADJ_REASON_GET_PROVIDER: 198 return AppProtoEnums.OOM_ADJ_REASON_GET_PROVIDER; 199 case OOM_ADJ_REASON_REMOVE_PROVIDER: 200 return AppProtoEnums.OOM_ADJ_REASON_REMOVE_PROVIDER; 201 case OOM_ADJ_REASON_UI_VISIBILITY: 202 return AppProtoEnums.OOM_ADJ_REASON_UI_VISIBILITY; 203 case OOM_ADJ_REASON_ALLOWLIST: 204 return AppProtoEnums.OOM_ADJ_REASON_ALLOWLIST; 205 case OOM_ADJ_REASON_PROCESS_BEGIN: 206 return AppProtoEnums.OOM_ADJ_REASON_PROCESS_BEGIN; 207 case OOM_ADJ_REASON_PROCESS_END: 208 return AppProtoEnums.OOM_ADJ_REASON_PROCESS_END; 209 case OOM_ADJ_REASON_SHORT_FGS_TIMEOUT: 210 return AppProtoEnums.OOM_ADJ_REASON_SHORT_FGS_TIMEOUT; 211 case OOM_ADJ_REASON_SYSTEM_INIT: 212 return AppProtoEnums.OOM_ADJ_REASON_SYSTEM_INIT; 213 case OOM_ADJ_REASON_BACKUP: 214 return AppProtoEnums.OOM_ADJ_REASON_BACKUP; 215 case OOM_ADJ_REASON_SHELL: 216 return AppProtoEnums.OOM_ADJ_REASON_SHELL; 217 case OOM_ADJ_REASON_REMOVE_TASK: 218 return AppProtoEnums.OOM_ADJ_REASON_REMOVE_TASK; 219 case OOM_ADJ_REASON_UID_IDLE: 220 return AppProtoEnums.OOM_ADJ_REASON_UID_IDLE; 221 case OOM_ADJ_REASON_STOP_SERVICE: 222 return AppProtoEnums.OOM_ADJ_REASON_STOP_SERVICE; 223 case OOM_ADJ_REASON_EXECUTING_SERVICE: 224 return AppProtoEnums.OOM_ADJ_REASON_EXECUTING_SERVICE; 225 case OOM_ADJ_REASON_RESTRICTION_CHANGE: 226 return AppProtoEnums.OOM_ADJ_REASON_RESTRICTION_CHANGE; 227 case OOM_ADJ_REASON_COMPONENT_DISABLED: 228 return AppProtoEnums.OOM_ADJ_REASON_COMPONENT_DISABLED; 229 case OOM_ADJ_REASON_FOLLOW_UP: 230 return AppProtoEnums.OOM_ADJ_REASON_FOLLOW_UP; 231 default: 232 return AppProtoEnums.OOM_ADJ_REASON_UNKNOWN_TO_PROTO; 233 } 234 } 235 oomAdjReasonToString(@omAdjReason int oomReason)236 public static final String oomAdjReasonToString(@OomAdjReason int oomReason) { 237 final String OOM_ADJ_REASON_METHOD = "updateOomAdj"; 238 switch (oomReason) { 239 case OOM_ADJ_REASON_NONE: 240 return OOM_ADJ_REASON_METHOD + "_meh"; 241 case OOM_ADJ_REASON_ACTIVITY: 242 return OOM_ADJ_REASON_METHOD + "_activityChange"; 243 case OOM_ADJ_REASON_FINISH_RECEIVER: 244 return OOM_ADJ_REASON_METHOD + "_finishReceiver"; 245 case OOM_ADJ_REASON_START_RECEIVER: 246 return OOM_ADJ_REASON_METHOD + "_startReceiver"; 247 case OOM_ADJ_REASON_BIND_SERVICE: 248 return OOM_ADJ_REASON_METHOD + "_bindService"; 249 case OOM_ADJ_REASON_UNBIND_SERVICE: 250 return OOM_ADJ_REASON_METHOD + "_unbindService"; 251 case OOM_ADJ_REASON_START_SERVICE: 252 return OOM_ADJ_REASON_METHOD + "_startService"; 253 case OOM_ADJ_REASON_GET_PROVIDER: 254 return OOM_ADJ_REASON_METHOD + "_getProvider"; 255 case OOM_ADJ_REASON_REMOVE_PROVIDER: 256 return OOM_ADJ_REASON_METHOD + "_removeProvider"; 257 case OOM_ADJ_REASON_UI_VISIBILITY: 258 return OOM_ADJ_REASON_METHOD + "_uiVisibility"; 259 case OOM_ADJ_REASON_ALLOWLIST: 260 return OOM_ADJ_REASON_METHOD + "_allowlistChange"; 261 case OOM_ADJ_REASON_PROCESS_BEGIN: 262 return OOM_ADJ_REASON_METHOD + "_processBegin"; 263 case OOM_ADJ_REASON_PROCESS_END: 264 return OOM_ADJ_REASON_METHOD + "_processEnd"; 265 case OOM_ADJ_REASON_SHORT_FGS_TIMEOUT: 266 return OOM_ADJ_REASON_METHOD + "_shortFgs"; 267 case OOM_ADJ_REASON_SYSTEM_INIT: 268 return OOM_ADJ_REASON_METHOD + "_systemInit"; 269 case OOM_ADJ_REASON_BACKUP: 270 return OOM_ADJ_REASON_METHOD + "_backup"; 271 case OOM_ADJ_REASON_SHELL: 272 return OOM_ADJ_REASON_METHOD + "_shell"; 273 case OOM_ADJ_REASON_REMOVE_TASK: 274 return OOM_ADJ_REASON_METHOD + "_removeTask"; 275 case OOM_ADJ_REASON_UID_IDLE: 276 return OOM_ADJ_REASON_METHOD + "_uidIdle"; 277 case OOM_ADJ_REASON_STOP_SERVICE: 278 return OOM_ADJ_REASON_METHOD + "_stopService"; 279 case OOM_ADJ_REASON_EXECUTING_SERVICE: 280 return OOM_ADJ_REASON_METHOD + "_executingService"; 281 case OOM_ADJ_REASON_RESTRICTION_CHANGE: 282 return OOM_ADJ_REASON_METHOD + "_restrictionChange"; 283 case OOM_ADJ_REASON_COMPONENT_DISABLED: 284 return OOM_ADJ_REASON_METHOD + "_componentDisabled"; 285 case OOM_ADJ_REASON_FOLLOW_UP: 286 return OOM_ADJ_REASON_METHOD + "_followUp"; 287 default: 288 return "_unknown"; 289 } 290 } 291 292 /** 293 * Flag {@link android.content.Context#BIND_INCLUDE_CAPABILITIES} is used 294 * to pass while-in-use capabilities from client process to bound service. In targetSdkVersion 295 * R and above, if client is a TOP activity, when this flag is present, bound service gets all 296 * while-in-use capabilities; when this flag is not present, bound service gets no while-in-use 297 * capability from client. 298 */ 299 @ChangeId 300 @EnabledAfter(targetSdkVersion=android.os.Build.VERSION_CODES.Q) 301 static final long PROCESS_CAPABILITY_CHANGE_ID = 136274596L; 302 303 /** 304 * In targetSdkVersion R and above, foreground service has camera and microphone while-in-use 305 * capability only when the {@link android.R.attr#foregroundServiceType} is configured as 306 * {@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_CAMERA} and 307 * {@link android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_MICROPHONE} respectively in the 308 * manifest file. 309 * In targetSdkVersion below R, foreground service automatically have camera and microphone 310 * capabilities. 311 */ 312 @ChangeId 313 @EnabledAfter(targetSdkVersion=android.os.Build.VERSION_CODES.Q) 314 static final long CAMERA_MICROPHONE_CAPABILITY_CHANGE_ID = 136219221L; 315 316 /** 317 * For apps targeting S+, this determines whether to use a shorter timeout before elevating the 318 * standby bucket to ACTIVE when apps start a foreground service. 319 */ 320 @ChangeId 321 @EnabledSince(targetSdkVersion = android.os.Build.VERSION_CODES.S) 322 static final long USE_SHORT_FGS_USAGE_INTERACTION_TIME = 183972877L; 323 324 /** 325 * Service for optimizing resource usage from background apps. 326 */ 327 CachedAppOptimizer mCachedAppOptimizer; 328 329 /** 330 * Re-rank apps getting a cache oom adjustment from lru to weighted order 331 * based on weighted scores for LRU, PSS and cache use count. 332 */ 333 CacheOomRanker mCacheOomRanker; 334 335 ActivityManagerConstants mConstants; 336 337 final long[] mTmpLong = new long[3]; 338 339 /** 340 * Current sequence id for oom_adj computation traversal. 341 */ 342 int mAdjSeq = 0; 343 344 /** 345 * Keep track of the number of service processes we last found, to 346 * determine on the next iteration which should be B services. 347 */ 348 int mNumServiceProcs = 0; 349 int mNewNumAServiceProcs = 0; 350 int mNewNumServiceProcs = 0; 351 352 /** 353 * Keep track of the non-cached/empty process we last found, to help 354 * determine how to distribute cached/empty processes next time. 355 */ 356 int mNumNonCachedProcs = 0; 357 358 /** 359 * Keep track of the number of cached hidden procs, to balance oom adj 360 * distribution between those and empty procs. 361 */ 362 int mNumCachedHiddenProcs = 0; 363 364 /** Track all uids that have actively running processes. */ 365 @CompositeRWLock({"mService", "mProcLock"}) 366 ActiveUids mActiveUids; 367 368 /** 369 * The handler to execute {@link #setProcessGroup} (it may be heavy if the process has many 370 * threads) for reducing the time spent in {@link #applyOomAdjLSP}. 371 */ 372 private final Handler mProcessGroupHandler; 373 374 protected final int[] mTmpSchedGroup = new int[1]; 375 376 final ActivityManagerService mService; 377 final Injector mInjector; 378 final ProcessList mProcessList; 379 final ActivityManagerGlobalLock mProcLock; 380 381 private final int mNumSlots; 382 protected final ArrayList<ProcessRecord> mTmpProcessList = new ArrayList<ProcessRecord>(); 383 protected final ArrayList<ProcessRecord> mTmpProcessList2 = new ArrayList<ProcessRecord>(); 384 protected final ArrayList<UidRecord> mTmpBecameIdle = new ArrayList<UidRecord>(); 385 protected final ActiveUids mTmpUidRecords; 386 protected final ArrayDeque<ProcessRecord> mTmpQueue; 387 protected final ArraySet<ProcessRecord> mTmpProcessSet = new ArraySet<>(); 388 protected final ArraySet<ProcessRecord> mPendingProcessSet = new ArraySet<>(); 389 protected final ArraySet<ProcessRecord> mProcessesInCycle = new ArraySet<>(); 390 391 /** 392 * List of processes that we want to batch for LMKD to adjust their respective 393 * OOM scores. 394 */ 395 @GuardedBy("mService") 396 protected final ArrayList<ProcessRecord> mProcsToOomAdj = new ArrayList<ProcessRecord>(); 397 398 /** 399 * Flag to mark if there is an ongoing oomAdjUpdate: potentially the oomAdjUpdate 400 * could be called recursively because of the indirect calls during the update; 401 * however the oomAdjUpdate itself doesn't support recursion - in this case we'd 402 * have to queue up the new targets found during the update, and perform another 403 * round of oomAdjUpdate at the end of last update. 404 */ 405 @GuardedBy("mService") 406 private boolean mOomAdjUpdateOngoing = false; 407 408 /** 409 * Flag to mark if there is a pending full oomAdjUpdate. 410 */ 411 @GuardedBy("mService") 412 private boolean mPendingFullOomAdjUpdate = false; 413 414 /** 415 * Most recent reason string. We update it in sync with the trace. 416 */ 417 @OomAdjReason 418 protected int mLastReason; 419 420 private final OomAdjusterDebugLogger mLogger; 421 422 /** 423 * The process state of the current TOP app. 424 */ 425 @GuardedBy("mService") 426 protected int mProcessStateCurTop = PROCESS_STATE_TOP; 427 428 @GuardedBy("mService") 429 private final ArraySet<ProcessRecord> mFollowUpUpdateSet = new ArraySet<>(); 430 431 private static final long NO_FOLLOW_UP_TIME = Long.MAX_VALUE; 432 @GuardedBy("mService") 433 private long mNextFollowUpUpdateUptimeMs = NO_FOLLOW_UP_TIME; 434 435 @VisibleForTesting 436 public static class Injector { isChangeEnabled(@achedCompatChangeId int cachedCompatChangeId, ApplicationInfo app, boolean defaultValue)437 boolean isChangeEnabled(@CachedCompatChangeId int cachedCompatChangeId, 438 ApplicationInfo app, boolean defaultValue) { 439 return PlatformCompatCache.getInstance() 440 .isChangeEnabled(cachedCompatChangeId, app, defaultValue); 441 } 442 getUptimeMillis()443 long getUptimeMillis() { 444 return SystemClock.uptimeMillis(); 445 } 446 getElapsedRealtimeMillis()447 long getElapsedRealtimeMillis() { 448 return SystemClock.elapsedRealtime(); 449 } 450 } 451 isChangeEnabled(@achedCompatChangeId int cachedCompatChangeId, ApplicationInfo app, boolean defaultValue)452 boolean isChangeEnabled(@CachedCompatChangeId int cachedCompatChangeId, 453 ApplicationInfo app, boolean defaultValue) { 454 return mInjector.isChangeEnabled(cachedCompatChangeId, app, defaultValue); 455 } 456 OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids)457 OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids) { 458 this(service, processList, activeUids, createAdjusterThread()); 459 } 460 createAdjusterThread()461 static ServiceThread createAdjusterThread() { 462 // The process group is usually critical to the response time of foreground app, so the 463 // setter should apply it as soon as possible. 464 final ServiceThread adjusterThread = 465 new ServiceThread(TAG, THREAD_PRIORITY_TOP_APP_BOOST, false /* allowIo */); 466 adjusterThread.start(); 467 return adjusterThread; 468 } 469 OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids, ServiceThread adjusterThread)470 OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids, 471 ServiceThread adjusterThread) { 472 this(service, processList, activeUids, adjusterThread, new Injector()); 473 } 474 OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids, Injector injector)475 OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids, 476 Injector injector) { 477 this(service, processList, activeUids, createAdjusterThread(), injector); 478 } 479 OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids, ServiceThread adjusterThread, Injector injector)480 OomAdjuster(ActivityManagerService service, ProcessList processList, ActiveUids activeUids, 481 ServiceThread adjusterThread, Injector injector) { 482 mService = service; 483 mInjector = injector; 484 mProcessList = processList; 485 mProcLock = service.mProcLock; 486 mActiveUids = activeUids; 487 488 mConstants = mService.mConstants; 489 mCachedAppOptimizer = new CachedAppOptimizer(mService); 490 mCacheOomRanker = new CacheOomRanker(service); 491 492 mLogger = new OomAdjusterDebugLogger(this, mService.mConstants); 493 494 mProcessGroupHandler = new Handler(adjusterThread.getLooper(), msg -> { 495 final int pid = msg.arg1; 496 final int group = msg.arg2; 497 if (pid == ActivityManagerService.MY_PID) { 498 // Skip setting the process group for system_server, keep it as default. 499 return true; 500 } 501 final boolean traceEnabled = Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER); 502 if (traceEnabled) { 503 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "setProcessGroup " 504 + msg.obj + " to " + group); 505 } 506 try { 507 setProcessGroup(pid, group); 508 } catch (Exception e) { 509 if (DEBUG_ALL) { 510 Slog.w(TAG, "Failed setting process group of " + pid + " to " + group, e); 511 } 512 } finally { 513 if (traceEnabled) { 514 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 515 } 516 } 517 return true; 518 }); 519 mTmpUidRecords = new ActiveUids(service, false); 520 mTmpQueue = new ArrayDeque<ProcessRecord>(mConstants.CUR_MAX_CACHED_PROCESSES << 1); 521 mNumSlots = ((CACHED_APP_MAX_ADJ - CACHED_APP_MIN_ADJ + 1) >> 1) 522 / CACHED_APP_IMPORTANCE_LEVELS; 523 } 524 initSettings()525 void initSettings() { 526 mCachedAppOptimizer.init(); 527 mCacheOomRanker.init(ActivityThread.currentApplication().getMainExecutor()); 528 if (mService.mConstants.KEEP_WARMING_SERVICES.size() > 0) { 529 final IntentFilter filter = new IntentFilter(Intent.ACTION_USER_SWITCHED); 530 mService.mContext.registerReceiverForAllUsers(new BroadcastReceiver() { 531 @Override 532 public void onReceive(Context context, Intent intent) { 533 synchronized (mService) { 534 handleUserSwitchedLocked(); 535 } 536 } 537 }, filter, null, mService.mHandler); 538 } 539 } 540 541 /** 542 * Update the keep-warming service flags upon user switches 543 */ 544 @VisibleForTesting 545 @GuardedBy("mService") handleUserSwitchedLocked()546 void handleUserSwitchedLocked() { 547 mProcessList.forEachLruProcessesLOSP(false, 548 this::updateKeepWarmIfNecessaryForProcessLocked); 549 } 550 551 @GuardedBy("mService") updateKeepWarmIfNecessaryForProcessLocked(final ProcessRecord app)552 private void updateKeepWarmIfNecessaryForProcessLocked(final ProcessRecord app) { 553 final ArraySet<ComponentName> warmServices = mService.mConstants.KEEP_WARMING_SERVICES; 554 boolean includeWarmPkg = false; 555 final PackageList pkgList = app.getPkgList(); 556 for (int j = warmServices.size() - 1; j >= 0; j--) { 557 if (pkgList.containsKey(warmServices.valueAt(j).getPackageName())) { 558 includeWarmPkg = true; 559 break; 560 } 561 } 562 if (!includeWarmPkg) { 563 return; 564 } 565 final ProcessServiceRecord psr = app.mServices; 566 for (int j = psr.numberOfRunningServices() - 1; j >= 0; j--) { 567 psr.getRunningServiceAt(j).updateKeepWarmLocked(); 568 } 569 } 570 571 /** 572 * Update OomAdj for all processes in LRU list 573 */ 574 @GuardedBy("mService") updateOomAdjLocked(@omAdjReason int oomAdjReason)575 void updateOomAdjLocked(@OomAdjReason int oomAdjReason) { 576 synchronized (mProcLock) { 577 updateOomAdjLSP(oomAdjReason); 578 } 579 } 580 581 @GuardedBy({"mService", "mProcLock"}) updateOomAdjLSP(@omAdjReason int oomAdjReason)582 private void updateOomAdjLSP(@OomAdjReason int oomAdjReason) { 583 if (checkAndEnqueueOomAdjTargetLocked(null)) { 584 // Simply return as there is an oomAdjUpdate ongoing 585 return; 586 } 587 try { 588 mOomAdjUpdateOngoing = true; 589 performUpdateOomAdjLSP(oomAdjReason); 590 } finally { 591 // Kick off the handling of any pending targets enqueued during the above update 592 mOomAdjUpdateOngoing = false; 593 updateOomAdjPendingTargetsLocked(oomAdjReason); 594 } 595 } 596 597 @GuardedBy({"mService", "mProcLock"}) performUpdateOomAdjLSP(@omAdjReason int oomAdjReason)598 protected void performUpdateOomAdjLSP(@OomAdjReason int oomAdjReason) { 599 final ProcessRecord topApp = mService.getTopApp(); 600 mProcessStateCurTop = mService.mAtmInternal.getTopProcessState(); 601 // Clear any pending ones because we are doing a full update now. 602 mPendingProcessSet.clear(); 603 mService.mAppProfiler.mHasPreviousProcess = mService.mAppProfiler.mHasHomeProcess = false; 604 updateOomAdjInnerLSP(oomAdjReason, topApp , null, null, true, true); 605 } 606 607 /** 608 * Update OomAdj for specific process and its reachable processes (with direction/indirect 609 * bindings from this process); Note its clients' proc state won't be re-evaluated if this proc 610 * is hosting any service/content provider. 611 * 612 * @param app The process to update, or null to update all processes 613 * @param oomAdjReason 614 */ 615 @GuardedBy("mService") updateOomAdjLocked(ProcessRecord app, @OomAdjReason int oomAdjReason)616 boolean updateOomAdjLocked(ProcessRecord app, @OomAdjReason int oomAdjReason) { 617 synchronized (mProcLock) { 618 return updateOomAdjLSP(app, oomAdjReason); 619 } 620 } 621 622 @GuardedBy({"mService", "mProcLock"}) updateOomAdjLSP(ProcessRecord app, @OomAdjReason int oomAdjReason)623 private boolean updateOomAdjLSP(ProcessRecord app, @OomAdjReason int oomAdjReason) { 624 if (app == null || !mConstants.OOMADJ_UPDATE_QUICK) { 625 updateOomAdjLSP(oomAdjReason); 626 return true; 627 } 628 629 if (checkAndEnqueueOomAdjTargetLocked(app)) { 630 // Simply return true as there is an oomAdjUpdate ongoing 631 return true; 632 } 633 634 try { 635 mOomAdjUpdateOngoing = true; 636 return performUpdateOomAdjLSP(app, oomAdjReason); 637 } finally { 638 // Kick off the handling of any pending targets enqueued during the above update 639 mOomAdjUpdateOngoing = false; 640 updateOomAdjPendingTargetsLocked(oomAdjReason); 641 } 642 } 643 644 @GuardedBy({"mService", "mProcLock"}) performUpdateOomAdjLSP(ProcessRecord app, @OomAdjReason int oomAdjReason)645 protected boolean performUpdateOomAdjLSP(ProcessRecord app, @OomAdjReason int oomAdjReason) { 646 final ProcessRecord topApp = mService.getTopApp(); 647 648 mLastReason = oomAdjReason; 649 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, oomAdjReasonToString(oomAdjReason)); 650 651 final ProcessStateRecord state = app.mState; 652 653 // Next to find out all its reachable processes 654 ArrayList<ProcessRecord> processes = mTmpProcessList; 655 ActiveUids uids = mTmpUidRecords; 656 mPendingProcessSet.add(app); 657 mProcessStateCurTop = enqueuePendingTopAppIfNecessaryLSP(); 658 659 boolean containsCycle = collectReachableProcessesLocked(mPendingProcessSet, 660 processes, uids); 661 662 // Clear the pending set as they should've been included in 'processes'. 663 mPendingProcessSet.clear(); 664 665 int size = processes.size(); 666 if (size > 0) { 667 // Update these reachable processes 668 updateOomAdjInnerLSP(oomAdjReason, topApp, processes, uids, containsCycle, false); 669 } else if (state.getCurRawAdj() == UNKNOWN_ADJ) { 670 // In case the app goes from non-cached to cached but it doesn't have other reachable 671 // processes, its adj could be still unknown as of now, assign one. 672 processes.add(app); 673 assignCachedAdjIfNecessary(processes); 674 applyOomAdjLSP(app, false, mInjector.getUptimeMillis(), 675 mInjector.getElapsedRealtimeMillis(), oomAdjReason); 676 } 677 mTmpProcessList.clear(); 678 mService.clearPendingTopAppLocked(); 679 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 680 return true; 681 } 682 683 @GuardedBy({"mService", "mProcLock"}) enqueuePendingTopAppIfNecessaryLSP()684 protected int enqueuePendingTopAppIfNecessaryLSP() { 685 final int prevTopProcessState = mService.mAtmInternal.getTopProcessState(); 686 mService.enqueuePendingTopAppIfNecessaryLocked(); 687 final int topProcessState = mService.mAtmInternal.getTopProcessState(); 688 if (prevTopProcessState != topProcessState) { 689 // Unlikely but possible: WM just updated the top process state, it may have 690 // enqueued the new top app to the pending top UID list. Enqueue that one here too. 691 mService.enqueuePendingTopAppIfNecessaryLocked(); 692 } 693 return topProcessState; 694 } 695 696 /** 697 * Collect the reachable processes from the given {@code apps}, the result will be 698 * returned in the given {@code processes}, which will include the processes from 699 * the given {@code apps}. 700 */ 701 @GuardedBy("mService") collectReachableProcessesLocked(ArraySet<ProcessRecord> apps, ArrayList<ProcessRecord> processes, ActiveUids uids)702 protected boolean collectReachableProcessesLocked(ArraySet<ProcessRecord> apps, 703 ArrayList<ProcessRecord> processes, ActiveUids uids) { 704 final ArrayDeque<ProcessRecord> queue = mTmpQueue; 705 queue.clear(); 706 processes.clear(); 707 for (int i = 0, size = apps.size(); i < size; i++) { 708 final ProcessRecord app = apps.valueAt(i); 709 app.mState.setReachable(true); 710 queue.offer(app); 711 } 712 713 uids.clear(); 714 715 // Track if any of them reachables could include a cycle 716 boolean containsCycle = false; 717 // Scan downstreams of the process record 718 for (ProcessRecord pr = queue.poll(); pr != null; pr = queue.poll()) { 719 processes.add(pr); 720 final UidRecord uidRec = pr.getUidRecord(); 721 if (uidRec != null) { 722 uids.put(uidRec.getUid(), uidRec); 723 } 724 final ProcessServiceRecord psr = pr.mServices; 725 for (int i = psr.numberOfConnections() - 1; i >= 0; i--) { 726 ConnectionRecord cr = psr.getConnectionAt(i); 727 ProcessRecord service = cr.hasFlag(ServiceInfo.FLAG_ISOLATED_PROCESS) 728 ? cr.binding.service.isolationHostProc : cr.binding.service.app; 729 if (service == null || service == pr 730 || ((service.mState.getMaxAdj() >= ProcessList.SYSTEM_ADJ) 731 && (service.mState.getMaxAdj() < FOREGROUND_APP_ADJ))) { 732 continue; 733 } 734 containsCycle |= service.mState.isReachable(); 735 if (service.mState.isReachable()) { 736 continue; 737 } 738 if (cr.hasFlag(Context.BIND_WAIVE_PRIORITY) 739 && cr.notHasFlag(Context.BIND_TREAT_LIKE_ACTIVITY 740 | Context.BIND_ADJUST_WITH_ACTIVITY)) { 741 continue; 742 } 743 queue.offer(service); 744 service.mState.setReachable(true); 745 } 746 final ProcessProviderRecord ppr = pr.mProviders; 747 for (int i = ppr.numberOfProviderConnections() - 1; i >= 0; i--) { 748 ContentProviderConnection cpc = ppr.getProviderConnectionAt(i); 749 ProcessRecord provider = cpc.provider.proc; 750 if (provider == null || provider == pr 751 || ((provider.mState.getMaxAdj() >= ProcessList.SYSTEM_ADJ) 752 && (provider.mState.getMaxAdj() < FOREGROUND_APP_ADJ))) { 753 continue; 754 } 755 containsCycle |= provider.mState.isReachable(); 756 if (provider.mState.isReachable()) { 757 continue; 758 } 759 queue.offer(provider); 760 provider.mState.setReachable(true); 761 } 762 // See if this process has any corresponding SDK sandbox processes running, and if so 763 // scan them as well. 764 final List<ProcessRecord> sdkSandboxes = 765 mProcessList.getSdkSandboxProcessesForAppLocked(pr.uid); 766 final int numSdkSandboxes = sdkSandboxes != null ? sdkSandboxes.size() : 0; 767 for (int i = numSdkSandboxes - 1; i >= 0; i--) { 768 ProcessRecord sdkSandbox = sdkSandboxes.get(i); 769 containsCycle |= sdkSandbox.mState.isReachable(); 770 if (sdkSandbox.mState.isReachable()) { 771 continue; 772 } 773 queue.offer(sdkSandbox); 774 sdkSandbox.mState.setReachable(true); 775 } 776 // If this process is a sandbox itself, also scan the app on whose behalf its running 777 if (pr.isSdkSandbox) { 778 for (int is = psr.numberOfRunningServices() - 1; is >= 0; is--) { 779 ServiceRecord s = psr.getRunningServiceAt(is); 780 ArrayMap<IBinder, ArrayList<ConnectionRecord>> serviceConnections = 781 s.getConnections(); 782 for (int conni = serviceConnections.size() - 1; conni >= 0; conni--) { 783 ArrayList<ConnectionRecord> clist = serviceConnections.valueAt(conni); 784 for (int i = clist.size() - 1; i >= 0; i--) { 785 ConnectionRecord cr = clist.get(i); 786 ProcessRecord attributedApp = cr.binding.attributedClient; 787 if (attributedApp == null || attributedApp == pr 788 || ((attributedApp.mState.getMaxAdj() >= ProcessList.SYSTEM_ADJ) 789 && (attributedApp.mState.getMaxAdj() < FOREGROUND_APP_ADJ))) { 790 continue; 791 } 792 if (attributedApp.mState.isReachable()) { 793 continue; 794 } 795 queue.offer(attributedApp); 796 attributedApp.mState.setReachable(true); 797 } 798 } 799 } 800 } 801 } 802 803 int size = processes.size(); 804 if (size > 0) { 805 // Reverse the process list, since the updateOomAdjInnerLSP scans from the end of it. 806 for (int l = 0, r = size - 1; l < r; l++, r--) { 807 final ProcessRecord t = processes.get(l); 808 final ProcessRecord u = processes.get(r); 809 t.mState.setReachable(false); 810 u.mState.setReachable(false); 811 processes.set(l, u); 812 processes.set(r, t); 813 } 814 } 815 816 return containsCycle; 817 } 818 819 /** 820 * Enqueue the given process for a later oom adj update 821 */ 822 @GuardedBy("mService") enqueueOomAdjTargetLocked(ProcessRecord app)823 void enqueueOomAdjTargetLocked(ProcessRecord app) { 824 if (app != null && app.mState.getMaxAdj() > FOREGROUND_APP_ADJ) { 825 mPendingProcessSet.add(app); 826 } 827 } 828 829 @GuardedBy("mService") removeOomAdjTargetLocked(ProcessRecord app, boolean procDied)830 void removeOomAdjTargetLocked(ProcessRecord app, boolean procDied) { 831 if (app != null) { 832 mPendingProcessSet.remove(app); 833 if (procDied) { 834 PlatformCompatCache.getInstance().invalidate(app.info); 835 } 836 } 837 } 838 839 /** 840 * Check if there is an ongoing oomAdjUpdate, enqueue the given process record 841 * to {@link #mPendingProcessSet} if there is one. 842 * 843 * @param app The target app to get an oomAdjUpdate, or a full oomAdjUpdate if it's null. 844 * @return {@code true} if there is an ongoing oomAdjUpdate. 845 */ 846 @GuardedBy("mService") checkAndEnqueueOomAdjTargetLocked(@ullable ProcessRecord app)847 private boolean checkAndEnqueueOomAdjTargetLocked(@Nullable ProcessRecord app) { 848 if (!mOomAdjUpdateOngoing) { 849 return false; 850 } 851 if (app != null) { 852 mPendingProcessSet.add(app); 853 } else { 854 mPendingFullOomAdjUpdate = true; 855 } 856 return true; 857 } 858 859 /** 860 * Kick off an oom adj update pass for the pending targets which are enqueued via 861 * {@link #enqueueOomAdjTargetLocked}. 862 */ 863 @GuardedBy("mService") updateOomAdjPendingTargetsLocked(@omAdjReason int oomAdjReason)864 void updateOomAdjPendingTargetsLocked(@OomAdjReason int oomAdjReason) { 865 // First check if there is pending full update 866 if (mPendingFullOomAdjUpdate) { 867 mPendingFullOomAdjUpdate = false; 868 mPendingProcessSet.clear(); 869 updateOomAdjLocked(oomAdjReason); 870 return; 871 } 872 if (mPendingProcessSet.isEmpty()) { 873 return; 874 } 875 876 if (mOomAdjUpdateOngoing) { 877 // There's another oomAdjUpdate ongoing, return from here now; 878 // that ongoing update would call us again at the end of it. 879 return; 880 } 881 try { 882 mOomAdjUpdateOngoing = true; 883 performUpdateOomAdjPendingTargetsLocked(oomAdjReason); 884 } finally { 885 // Kick off the handling of any pending targets enqueued during the above update 886 mOomAdjUpdateOngoing = false; 887 updateOomAdjPendingTargetsLocked(oomAdjReason); 888 } 889 } 890 891 @GuardedBy("mService") updateOomAdjFollowUpTargetsLocked()892 void updateOomAdjFollowUpTargetsLocked() { 893 final long now = mInjector.getUptimeMillis(); 894 long nextFollowUpUptimeMs = Long.MAX_VALUE; 895 mNextFollowUpUpdateUptimeMs = NO_FOLLOW_UP_TIME; 896 for (int i = mFollowUpUpdateSet.size() - 1; i >= 0; i--) { 897 final ProcessRecord proc = mFollowUpUpdateSet.valueAtUnchecked(i); 898 final long followUpUptimeMs = proc.mState.getFollowupUpdateUptimeMs(); 899 900 if (proc.isKilled()) { 901 // Process is dead, just remove from follow up set. 902 mFollowUpUpdateSet.removeAt(i); 903 } else if (followUpUptimeMs <= now) { 904 // Add processes that need a follow up update. 905 mPendingProcessSet.add(proc); 906 proc.mState.setFollowupUpdateUptimeMs(NO_FOLLOW_UP_TIME); 907 mFollowUpUpdateSet.removeAt(i); 908 } else if (followUpUptimeMs < nextFollowUpUptimeMs) { 909 // Figure out when to schedule the next follow up update. 910 nextFollowUpUptimeMs = followUpUptimeMs; 911 } else if (followUpUptimeMs == NO_FOLLOW_UP_TIME) { 912 // The follow up is no longer needed for this process. 913 mFollowUpUpdateSet.removeAt(i); 914 } 915 } 916 917 if (nextFollowUpUptimeMs != Long.MAX_VALUE) { 918 // There is still at least one process that needs a follow up. 919 scheduleFollowUpOomAdjusterUpdateLocked(nextFollowUpUptimeMs, now); 920 } 921 922 updateOomAdjPendingTargetsLocked(OOM_ADJ_REASON_FOLLOW_UP); 923 } 924 925 @GuardedBy("mService") performUpdateOomAdjPendingTargetsLocked(@omAdjReason int oomAdjReason)926 protected void performUpdateOomAdjPendingTargetsLocked(@OomAdjReason int oomAdjReason) { 927 final ProcessRecord topApp = mService.getTopApp(); 928 929 mLastReason = oomAdjReason; 930 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, oomAdjReasonToString(oomAdjReason)); 931 mProcessStateCurTop = enqueuePendingTopAppIfNecessaryLSP(); 932 933 final ArrayList<ProcessRecord> processes = mTmpProcessList; 934 final ActiveUids uids = mTmpUidRecords; 935 collectReachableProcessesLocked(mPendingProcessSet, processes, uids); 936 mPendingProcessSet.clear(); 937 synchronized (mProcLock) { 938 updateOomAdjInnerLSP(oomAdjReason, topApp, processes, uids, true, false); 939 } 940 processes.clear(); 941 mService.clearPendingTopAppLocked(); 942 943 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 944 } 945 946 /** 947 * Update OomAdj for all processes within the given list (could be partial), or the whole LRU 948 * list if the given list is null; when it's partial update, each process's client proc won't 949 * get evaluated recursively here. 950 * 951 * <p>Note: If the given {@code processes} is not null, the expectation to it is, the caller 952 * must have called {@link collectReachableProcessesLocked} on it. 953 */ 954 @GuardedBy({"mService", "mProcLock"}) updateOomAdjInnerLSP(@omAdjReason int oomAdjReason, final ProcessRecord topApp, ArrayList<ProcessRecord> processes, ActiveUids uids, boolean potentialCycles, boolean startProfiling)955 private void updateOomAdjInnerLSP(@OomAdjReason int oomAdjReason, final ProcessRecord topApp, 956 ArrayList<ProcessRecord> processes, ActiveUids uids, boolean potentialCycles, 957 boolean startProfiling) { 958 final boolean fullUpdate = processes == null; 959 final ArrayList<ProcessRecord> activeProcesses = fullUpdate 960 ? mProcessList.getLruProcessesLOSP() : processes; 961 ActiveUids activeUids = uids; 962 if (activeUids == null) { 963 final int numUids = mActiveUids.size(); 964 activeUids = mTmpUidRecords; 965 activeUids.clear(); 966 for (int i = 0; i < numUids; i++) { 967 UidRecord uidRec = mActiveUids.valueAt(i); 968 activeUids.put(uidRec.getUid(), uidRec); 969 } 970 } 971 972 mLastReason = oomAdjReason; 973 if (startProfiling) { 974 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, oomAdjReasonToString(oomAdjReason)); 975 } 976 final long now = mInjector.getUptimeMillis(); 977 final long nowElapsed = mInjector.getElapsedRealtimeMillis(); 978 final long oldTime = now - mConstants.mMaxEmptyTimeMillis; 979 final int numProc = activeProcesses.size(); 980 981 mAdjSeq++; 982 if (fullUpdate) { 983 mNewNumServiceProcs = 0; 984 mNewNumAServiceProcs = 0; 985 } 986 987 // Reset state in all uid records. 988 resetUidRecordsLsp(activeUids); 989 990 boolean retryCycles = false; 991 boolean computeClients = fullUpdate || potentialCycles; 992 993 // need to reset cycle state before calling computeOomAdjLSP because of service conns 994 for (int i = numProc - 1; i >= 0; i--) { 995 ProcessRecord app = activeProcesses.get(i); 996 final ProcessStateRecord state = app.mState; 997 state.setReachable(false); 998 // No need to compute again it has been evaluated in previous iteration 999 if (state.getAdjSeq() != mAdjSeq) { 1000 state.setContainsCycle(false); 1001 state.setCurRawProcState(PROCESS_STATE_CACHED_EMPTY); 1002 state.setCurRawAdj(UNKNOWN_ADJ); 1003 state.setSetCapability(PROCESS_CAPABILITY_NONE); 1004 state.resetCachedInfo(); 1005 state.setCurBoundByNonBgRestrictedApp(false); 1006 } 1007 } 1008 mProcessesInCycle.clear(); 1009 for (int i = numProc - 1; i >= 0; i--) { 1010 ProcessRecord app = activeProcesses.get(i); 1011 final ProcessStateRecord state = app.mState; 1012 if (!app.isKilledByAm() && app.getThread() != null) { 1013 state.setProcStateChanged(false); 1014 app.mOptRecord.setLastOomAdjChangeReason(oomAdjReason); 1015 // It won't enter cycle if not computing clients. 1016 computeOomAdjLSP(app, UNKNOWN_ADJ, topApp, fullUpdate, now, false, 1017 computeClients, oomAdjReason, true); 1018 // if any app encountered a cycle, we need to perform an additional loop later 1019 retryCycles |= state.containsCycle(); 1020 // Keep the completedAdjSeq to up to date. 1021 state.setCompletedAdjSeq(mAdjSeq); 1022 } 1023 } 1024 1025 if (mCacheOomRanker.useOomReranking()) { 1026 mCacheOomRanker.reRankLruCachedAppsLSP(mProcessList.getLruProcessesLSP(), 1027 mProcessList.getLruProcessServiceStartLOSP()); 1028 } 1029 1030 if (computeClients) { // There won't be cycles if we didn't compute clients above. 1031 // Cycle strategy: 1032 // - Retry computing any process that has encountered a cycle. 1033 // - Continue retrying until no process was promoted. 1034 // - Iterate from least important to most important. 1035 int cycleCount = 0; 1036 while (retryCycles && cycleCount < 10) { 1037 cycleCount++; 1038 retryCycles = false; 1039 1040 for (int i = 0; i < numProc; i++) { 1041 ProcessRecord app = activeProcesses.get(i); 1042 final ProcessStateRecord state = app.mState; 1043 if (!app.isKilledByAm() && app.getThread() != null && state.containsCycle()) { 1044 state.decAdjSeq(); 1045 state.decCompletedAdjSeq(); 1046 } 1047 } 1048 1049 for (int i = 0; i < numProc; i++) { 1050 ProcessRecord app = activeProcesses.get(i); 1051 final ProcessStateRecord state = app.mState; 1052 if (!app.isKilledByAm() && app.getThread() != null && state.containsCycle()) { 1053 if (computeOomAdjLSP(app, UNKNOWN_ADJ, topApp, true, now, 1054 true, true, oomAdjReason, true)) { 1055 retryCycles = true; 1056 } 1057 } 1058 } 1059 } 1060 } 1061 mProcessesInCycle.clear(); 1062 1063 assignCachedAdjIfNecessary(mProcessList.getLruProcessesLOSP()); 1064 1065 postUpdateOomAdjInnerLSP(oomAdjReason, activeUids, now, nowElapsed, oldTime, true); 1066 1067 if (startProfiling) { 1068 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1069 } 1070 } 1071 1072 @GuardedBy({"mService", "mProcLock"}) resetUidRecordsLsp(@onNull ActiveUids activeUids)1073 private void resetUidRecordsLsp(@NonNull ActiveUids activeUids) { 1074 // Reset state in all uid records. 1075 for (int i = activeUids.size() - 1; i >= 0; i--) { 1076 final UidRecord uidRec = activeUids.valueAt(i); 1077 if (DEBUG_UID_OBSERVERS) { 1078 Slog.i(TAG_UID_OBSERVERS, "Starting update of " + uidRec); 1079 } 1080 uidRec.reset(); 1081 } 1082 } 1083 1084 @GuardedBy({"mService", "mProcLock"}) postUpdateOomAdjInnerLSP(@omAdjReason int oomAdjReason, ActiveUids activeUids, long now, long nowElapsed, long oldTime, boolean doingAll)1085 protected void postUpdateOomAdjInnerLSP(@OomAdjReason int oomAdjReason, ActiveUids activeUids, 1086 long now, long nowElapsed, long oldTime, boolean doingAll) { 1087 mNumNonCachedProcs = 0; 1088 mNumCachedHiddenProcs = 0; 1089 1090 updateAndTrimProcessLSP(now, nowElapsed, oldTime, activeUids, 1091 oomAdjReason, doingAll); 1092 mNumServiceProcs = mNewNumServiceProcs; 1093 1094 if (mService.mAlwaysFinishActivities) { 1095 // Need to do this on its own message because the stack may not 1096 // be in a consistent state at this point. 1097 mService.mAtmInternal.scheduleDestroyAllActivities("always-finish"); 1098 } 1099 1100 updateUidsLSP(activeUids, nowElapsed); 1101 1102 synchronized (mService.mProcessStats.mLock) { 1103 final long nowUptime = mInjector.getUptimeMillis(); 1104 if (mService.mProcessStats.shouldWriteNowLocked(nowUptime)) { 1105 mService.mHandler.post(new ActivityManagerService.ProcStatsRunnable(mService, 1106 mService.mProcessStats)); 1107 } 1108 1109 // Run this after making sure all procstates are updated. 1110 mService.mProcessStats.updateTrackingAssociationsLocked(mAdjSeq, nowUptime); 1111 } 1112 1113 if (DEBUG_OOM_ADJ) { 1114 final long duration = mInjector.getUptimeMillis() - now; 1115 if (false) { 1116 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms", 1117 new RuntimeException("here").fillInStackTrace()); 1118 } else { 1119 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms"); 1120 } 1121 } 1122 } 1123 1124 @GuardedBy({"mService", "mProcLock"}) assignCachedAdjIfNecessary(ArrayList<ProcessRecord> lruList)1125 protected void assignCachedAdjIfNecessary(ArrayList<ProcessRecord> lruList) { 1126 final int numLru = lruList.size(); 1127 if (mConstants.USE_TIERED_CACHED_ADJ) { 1128 final long now = mInjector.getUptimeMillis(); 1129 for (int i = numLru - 1; i >= 0; i--) { 1130 ProcessRecord app = lruList.get(i); 1131 final ProcessStateRecord state = app.mState; 1132 final ProcessCachedOptimizerRecord opt = app.mOptRecord; 1133 if (!app.isKilledByAm() && app.getThread() != null && state.getCurAdj() 1134 >= UNKNOWN_ADJ) { 1135 final ProcessServiceRecord psr = app.mServices; 1136 int targetAdj = CACHED_APP_MIN_ADJ; 1137 1138 if (opt != null && opt.isFreezeExempt()) { 1139 // BIND_WAIVE_PRIORITY and the like get oom_adj 900 1140 targetAdj += 0; 1141 } else if ((state.getSetAdj() >= CACHED_APP_MIN_ADJ) 1142 && (state.getLastStateTime() 1143 + mConstants.TIERED_CACHED_ADJ_DECAY_TIME) < now) { 1144 // Older cached apps get 950 1145 targetAdj += 50; 1146 } else { 1147 // Newer cached apps get 910 1148 targetAdj += 10; 1149 } 1150 state.setCurRawAdj(targetAdj); 1151 state.setCurAdj(psr.modifyRawOomAdj(targetAdj)); 1152 } 1153 } 1154 } else { 1155 // First update the OOM adjustment for each of the 1156 // application processes based on their current state. 1157 int curCachedAdj = CACHED_APP_MIN_ADJ; 1158 int nextCachedAdj = curCachedAdj + (CACHED_APP_IMPORTANCE_LEVELS * 2); 1159 int curCachedImpAdj = 0; 1160 int curEmptyAdj = CACHED_APP_MIN_ADJ + CACHED_APP_IMPORTANCE_LEVELS; 1161 int nextEmptyAdj = curEmptyAdj + (CACHED_APP_IMPORTANCE_LEVELS * 2); 1162 1163 final int emptyProcessLimit = mConstants.CUR_MAX_EMPTY_PROCESSES; 1164 final int cachedProcessLimit = mConstants.CUR_MAX_CACHED_PROCESSES 1165 - emptyProcessLimit; 1166 // Let's determine how many processes we have running vs. 1167 // how many slots we have for background processes; we may want 1168 // to put multiple processes in a slot of there are enough of 1169 // them. 1170 int numEmptyProcs = numLru - mNumNonCachedProcs - mNumCachedHiddenProcs; 1171 if (numEmptyProcs > cachedProcessLimit) { 1172 // If there are more empty processes than our limit on cached 1173 // processes, then use the cached process limit for the factor. 1174 // This ensures that the really old empty processes get pushed 1175 // down to the bottom, so if we are running low on memory we will 1176 // have a better chance at keeping around more cached processes 1177 // instead of a gazillion empty processes. 1178 numEmptyProcs = cachedProcessLimit; 1179 } 1180 int cachedFactor = (mNumCachedHiddenProcs > 0 1181 ? (mNumCachedHiddenProcs + mNumSlots - 1) : 1) 1182 / mNumSlots; 1183 if (cachedFactor < 1) cachedFactor = 1; 1184 1185 int emptyFactor = (numEmptyProcs + mNumSlots - 1) / mNumSlots; 1186 if (emptyFactor < 1) emptyFactor = 1; 1187 1188 int stepCached = -1; 1189 int stepEmpty = -1; 1190 int lastCachedGroup = 0; 1191 int lastCachedGroupImportance = 0; 1192 int lastCachedGroupUid = 0; 1193 1194 1195 for (int i = numLru - 1; i >= 0; i--) { 1196 ProcessRecord app = lruList.get(i); 1197 final ProcessStateRecord state = app.mState; 1198 // If we haven't yet assigned the final cached adj 1199 // to the process, do that now. 1200 if (!app.isKilledByAm() && app.getThread() != null && state.getCurAdj() 1201 >= UNKNOWN_ADJ) { 1202 final ProcessServiceRecord psr = app.mServices; 1203 switch (state.getCurProcState()) { 1204 case PROCESS_STATE_CACHED_ACTIVITY: 1205 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 1206 case ActivityManager.PROCESS_STATE_CACHED_RECENT: 1207 // Figure out the next cached level, taking into account groups. 1208 boolean inGroup = false; 1209 final int connectionGroup = psr.getConnectionGroup(); 1210 if (connectionGroup != 0) { 1211 final int connectionImportance = psr.getConnectionImportance(); 1212 if (lastCachedGroupUid == app.uid 1213 && lastCachedGroup == connectionGroup) { 1214 // This is in the same group as the last process, just tweak 1215 // adjustment by importance. 1216 if (connectionImportance > lastCachedGroupImportance) { 1217 lastCachedGroupImportance = connectionImportance; 1218 if (curCachedAdj < nextCachedAdj 1219 && curCachedAdj < CACHED_APP_MAX_ADJ) { 1220 curCachedImpAdj++; 1221 } 1222 } 1223 inGroup = true; 1224 } else { 1225 lastCachedGroupUid = app.uid; 1226 lastCachedGroup = connectionGroup; 1227 lastCachedGroupImportance = connectionImportance; 1228 } 1229 } 1230 if (!inGroup && curCachedAdj != nextCachedAdj) { 1231 stepCached++; 1232 curCachedImpAdj = 0; 1233 if (stepCached >= cachedFactor) { 1234 stepCached = 0; 1235 curCachedAdj = nextCachedAdj; 1236 nextCachedAdj += CACHED_APP_IMPORTANCE_LEVELS * 2; 1237 if (nextCachedAdj > CACHED_APP_MAX_ADJ) { 1238 nextCachedAdj = CACHED_APP_MAX_ADJ; 1239 } 1240 } 1241 } 1242 // This process is a cached process holding activities... 1243 // assign it the next cached value for that type, and then 1244 // step that cached level. 1245 state.setCurRawAdj(curCachedAdj + curCachedImpAdj); 1246 state.setCurAdj(psr.modifyRawOomAdj(curCachedAdj + curCachedImpAdj)); 1247 if (DEBUG_LRU) { 1248 Slog.d(TAG_LRU, "Assigning activity LRU #" + i 1249 + " adj: " + state.getCurAdj() 1250 + " (curCachedAdj=" + curCachedAdj 1251 + " curCachedImpAdj=" + curCachedImpAdj + ")"); 1252 } 1253 break; 1254 default: 1255 // Figure out the next cached level. 1256 if (curEmptyAdj != nextEmptyAdj) { 1257 stepEmpty++; 1258 if (stepEmpty >= emptyFactor) { 1259 stepEmpty = 0; 1260 curEmptyAdj = nextEmptyAdj; 1261 nextEmptyAdj += CACHED_APP_IMPORTANCE_LEVELS * 2; 1262 if (nextEmptyAdj > CACHED_APP_MAX_ADJ) { 1263 nextEmptyAdj = CACHED_APP_MAX_ADJ; 1264 } 1265 } 1266 } 1267 // For everything else, assign next empty cached process 1268 // level and bump that up. Note that this means that 1269 // long-running services that have dropped down to the 1270 // cached level will be treated as empty (since their process 1271 // state is still as a service), which is what we want. 1272 state.setCurRawAdj(curEmptyAdj); 1273 state.setCurAdj(psr.modifyRawOomAdj(curEmptyAdj)); 1274 if (DEBUG_LRU) { 1275 Slog.d(TAG_LRU, "Assigning empty LRU #" + i 1276 + " adj: " + state.getCurAdj() 1277 + " (curEmptyAdj=" + curEmptyAdj 1278 + ")"); 1279 } 1280 break; 1281 } 1282 } 1283 } 1284 } 1285 } 1286 private long mNextNoKillDebugMessageTime; 1287 1288 private double mLastFreeSwapPercent = 1.00; 1289 getFreeSwapPercent()1290 private static double getFreeSwapPercent() { 1291 return CachedAppOptimizer.getFreeSwapPercent(); 1292 } 1293 1294 @GuardedBy({"mService", "mProcLock"}) updateAndTrimProcessLSP(final long now, final long nowElapsed, final long oldTime, final ActiveUids activeUids, @OomAdjReason int oomAdjReason, boolean doingAll)1295 private void updateAndTrimProcessLSP(final long now, final long nowElapsed, 1296 final long oldTime, final ActiveUids activeUids, @OomAdjReason int oomAdjReason, 1297 boolean doingAll) { 1298 ArrayList<ProcessRecord> lruList = mProcessList.getLruProcessesLOSP(); 1299 final int numLru = lruList.size(); 1300 1301 final boolean doKillExcessiveProcesses = shouldKillExcessiveProcesses(now); 1302 if (!doKillExcessiveProcesses) { 1303 if (mNextNoKillDebugMessageTime < now) { 1304 Slog.d(TAG, "Not killing cached processes"); // STOPSHIP Remove it b/222365734 1305 mNextNoKillDebugMessageTime = now + 5000; // Every 5 seconds 1306 } 1307 } 1308 final int emptyProcessLimit = doKillExcessiveProcesses 1309 ? mConstants.CUR_MAX_EMPTY_PROCESSES : Integer.MAX_VALUE; 1310 final int cachedProcessLimit = doKillExcessiveProcesses 1311 ? (mConstants.CUR_MAX_CACHED_PROCESSES - emptyProcessLimit) : Integer.MAX_VALUE; 1312 int lastCachedGroup = 0; 1313 int lastCachedGroupUid = 0; 1314 int numCached = 0; 1315 int numCachedExtraGroup = 0; 1316 int numEmpty = 0; 1317 int numTrimming = 0; 1318 1319 boolean proactiveKillsEnabled = mConstants.PROACTIVE_KILLS_ENABLED; 1320 double lowSwapThresholdPercent = mConstants.LOW_SWAP_THRESHOLD_PERCENT; 1321 double freeSwapPercent = proactiveKillsEnabled ? getFreeSwapPercent() : 1.00; 1322 ProcessRecord lruCachedApp = null; 1323 1324 for (int i = numLru - 1; i >= 0; i--) { 1325 ProcessRecord app = lruList.get(i); 1326 final ProcessStateRecord state = app.mState; 1327 if (!app.isKilledByAm() && app.getThread() != null) { 1328 // We don't need to apply the update for the process which didn't get computed 1329 if (state.getCompletedAdjSeq() == mAdjSeq) { 1330 applyOomAdjLSP(app, doingAll, now, nowElapsed, oomAdjReason, true); 1331 } 1332 1333 if (app.isPendingFinishAttach()) { 1334 // Avoid trimming processes that are still initializing. If they aren't 1335 // hosting any components yet because they may be unfairly killed. 1336 // We however apply the oom scores set at #setAttachingProcessStatesLSP. 1337 updateAppUidRecLSP(app); 1338 continue; 1339 } 1340 1341 final ProcessServiceRecord psr = app.mServices; 1342 // Count the number of process types. 1343 switch (state.getCurProcState()) { 1344 case PROCESS_STATE_CACHED_ACTIVITY: 1345 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 1346 mNumCachedHiddenProcs++; 1347 numCached++; 1348 final int connectionGroup = psr.getConnectionGroup(); 1349 if (connectionGroup != 0) { 1350 if (lastCachedGroupUid == app.info.uid 1351 && lastCachedGroup == connectionGroup) { 1352 // If this process is the next in the same group, we don't 1353 // want it to count against our limit of the number of cached 1354 // processes, so bump up the group count to account for it. 1355 numCachedExtraGroup++; 1356 } else { 1357 lastCachedGroupUid = app.info.uid; 1358 lastCachedGroup = connectionGroup; 1359 } 1360 } else { 1361 lastCachedGroupUid = lastCachedGroup = 0; 1362 } 1363 if ((numCached - numCachedExtraGroup) > cachedProcessLimit) { 1364 app.killLocked("cached #" + numCached, 1365 "too many cached", 1366 ApplicationExitInfo.REASON_OTHER, 1367 ApplicationExitInfo.SUBREASON_TOO_MANY_CACHED, 1368 true); 1369 } else if (proactiveKillsEnabled) { 1370 lruCachedApp = app; 1371 } 1372 break; 1373 case PROCESS_STATE_CACHED_EMPTY: 1374 if (numEmpty > mConstants.CUR_TRIM_EMPTY_PROCESSES 1375 && app.getLastActivityTime() < oldTime) { 1376 app.killLocked("empty for " + ((now 1377 - app.getLastActivityTime()) / 1000) + "s", 1378 "empty for too long", 1379 ApplicationExitInfo.REASON_OTHER, 1380 ApplicationExitInfo.SUBREASON_TRIM_EMPTY, 1381 true); 1382 } else { 1383 numEmpty++; 1384 if (numEmpty > emptyProcessLimit) { 1385 app.killLocked("empty #" + numEmpty, 1386 "too many empty", 1387 ApplicationExitInfo.REASON_OTHER, 1388 ApplicationExitInfo.SUBREASON_TOO_MANY_EMPTY, 1389 true); 1390 } else if (proactiveKillsEnabled) { 1391 lruCachedApp = app; 1392 } 1393 } 1394 break; 1395 default: 1396 mNumNonCachedProcs++; 1397 break; 1398 } 1399 1400 // TODO: b/319163103 - limit isolated/sandbox trimming to just the processes 1401 // evaluated in the current update. 1402 if (app.isolated && psr.numberOfRunningServices() <= 0 1403 && app.getIsolatedEntryPoint() == null) { 1404 // If this is an isolated process, there are no services 1405 // running in it, and it's not a special process with a 1406 // custom entry point, then the process is no longer 1407 // needed. We agressively kill these because we can by 1408 // definition not re-use the same process again, and it is 1409 // good to avoid having whatever code was running in them 1410 // left sitting around after no longer needed. 1411 app.killLocked("isolated not needed", ApplicationExitInfo.REASON_OTHER, 1412 ApplicationExitInfo.SUBREASON_ISOLATED_NOT_NEEDED, true); 1413 } else if (app.isSdkSandbox && psr.numberOfRunningServices() <= 0 1414 && app.getActiveInstrumentation() == null) { 1415 // If this is an SDK sandbox process and there are no services running it, we 1416 // aggressively kill the sandbox as we usually don't want to re-use the same 1417 // sandbox again. 1418 app.killLocked("sandbox not needed", ApplicationExitInfo.REASON_OTHER, 1419 ApplicationExitInfo.SUBREASON_SDK_SANDBOX_NOT_NEEDED, true); 1420 } else { 1421 // Keeping this process, update its uid. 1422 updateAppUidRecLSP(app); 1423 } 1424 1425 if (state.getCurProcState() >= ActivityManager.PROCESS_STATE_HOME 1426 && !app.isKilledByAm()) { 1427 numTrimming++; 1428 } 1429 } 1430 } 1431 1432 if (!mProcsToOomAdj.isEmpty()) { 1433 ProcessList.batchSetOomAdj(mProcsToOomAdj); 1434 mProcsToOomAdj.clear(); 1435 } 1436 1437 if (proactiveKillsEnabled // Proactive kills enabled? 1438 && doKillExcessiveProcesses // Should kill excessive processes? 1439 && freeSwapPercent < lowSwapThresholdPercent // Swap below threshold? 1440 && lruCachedApp != null // If no cached app, let LMKD decide 1441 // If swap is non-decreasing, give reclaim a chance to catch up 1442 && freeSwapPercent < mLastFreeSwapPercent) { 1443 lruCachedApp.killLocked("swap low and too many cached", 1444 ApplicationExitInfo.REASON_OTHER, 1445 ApplicationExitInfo.SUBREASON_TOO_MANY_CACHED, 1446 true); 1447 } 1448 1449 mLastFreeSwapPercent = freeSwapPercent; 1450 1451 mService.mAppProfiler.updateLowMemStateLSP(numCached, numEmpty, numTrimming, now); 1452 } 1453 1454 @GuardedBy({"mService", "mProcLock"}) updateAppUidRecIfNecessaryLSP(final ProcessRecord app)1455 protected void updateAppUidRecIfNecessaryLSP(final ProcessRecord app) { 1456 if (!app.isKilledByAm() && app.getThread() != null) { 1457 if (app.isolated && app.mServices.numberOfRunningServices() <= 0 1458 && app.getIsolatedEntryPoint() == null) { 1459 // No op. 1460 } else { 1461 // Keeping this process, update its uid. 1462 updateAppUidRecLSP(app); 1463 } 1464 } 1465 } 1466 1467 @GuardedBy({"mService", "mProcLock"}) updateAppUidRecLSP(ProcessRecord app)1468 private void updateAppUidRecLSP(ProcessRecord app) { 1469 final UidRecord uidRec = app.getUidRecord(); 1470 if (uidRec != null) { 1471 final ProcessStateRecord state = app.mState; 1472 uidRec.setEphemeral(app.info.isInstantApp()); 1473 if (uidRec.getCurProcState() > state.getCurProcState()) { 1474 uidRec.setCurProcState(state.getCurProcState()); 1475 } 1476 if (app.mServices.hasForegroundServices()) { 1477 uidRec.setForegroundServices(true); 1478 } 1479 uidRec.setCurCapability(uidRec.getCurCapability() | state.getCurCapability()); 1480 } 1481 } 1482 1483 @GuardedBy({"mService", "mProcLock"}) updateUidsLSP(ActiveUids activeUids, final long nowElapsed)1484 protected void updateUidsLSP(ActiveUids activeUids, final long nowElapsed) { 1485 // This compares previously set procstate to the current procstate in regards to whether 1486 // or not the app's network access will be blocked. So, this needs to be called before 1487 // we update the UidRecord's procstate by calling {@link UidRecord#setSetProcState}. 1488 mProcessList.incrementProcStateSeqAndNotifyAppsLOSP(activeUids); 1489 1490 ArrayList<UidRecord> becameIdle = mTmpBecameIdle; 1491 becameIdle.clear(); 1492 1493 // Update from any uid changes. 1494 if (mService.mLocalPowerManager != null) { 1495 mService.mLocalPowerManager.startUidChanges(); 1496 } 1497 for (int i = activeUids.size() - 1; i >= 0; i--) { 1498 final UidRecord uidRec = activeUids.valueAt(i); 1499 if (uidRec.getCurProcState() != PROCESS_STATE_NONEXISTENT) { 1500 if (uidRec.getSetProcState() != uidRec.getCurProcState() 1501 || uidRec.getSetCapability() != uidRec.getCurCapability() 1502 || uidRec.isSetAllowListed() != uidRec.isCurAllowListed() 1503 || uidRec.getProcAdjChanged()) { 1504 int uidChange = 0; 1505 final boolean shouldLog = mLogger.shouldLog(uidRec.getUid()); 1506 if (DEBUG_UID_OBSERVERS) { 1507 Slog.i(TAG_UID_OBSERVERS, "Changes in " + uidRec 1508 + ": proc state from " + uidRec.getSetProcState() + " to " 1509 + uidRec.getCurProcState() + ", capability from " 1510 + uidRec.getSetCapability() + " to " + uidRec.getCurCapability() 1511 + ", allowlist from " + uidRec.isSetAllowListed() 1512 + " to " + uidRec.isCurAllowListed() 1513 + ", procAdjChanged: " + uidRec.getProcAdjChanged()); 1514 } 1515 if (ActivityManager.isProcStateBackground(uidRec.getCurProcState()) 1516 && !uidRec.isCurAllowListed()) { 1517 // UID is now in the background (and not on the temp allowlist). Was it 1518 // previously in the foreground (or on the temp allowlist)? 1519 // Or, it wasn't in the foreground / allowlist, but its last background 1520 // timestamp is also 0, this means it's never been in the 1521 // foreground / allowlist since it's born at all. 1522 if (!ActivityManager.isProcStateBackground(uidRec.getSetProcState()) 1523 || uidRec.isSetAllowListed() 1524 || uidRec.getLastBackgroundTime() == 0) { 1525 uidRec.setLastBackgroundTime(nowElapsed); 1526 if (shouldLog) { 1527 mLogger.logSetLastBackgroundTime(uidRec.getUid(), nowElapsed); 1528 } 1529 if (mService.mDeterministicUidIdle 1530 || !mService.mHandler.hasMessages(IDLE_UIDS_MSG)) { 1531 // Note: the background settle time is in elapsed realtime, while 1532 // the handler time base is uptime. All this means is that we may 1533 // stop background uids later than we had intended, but that only 1534 // happens because the device was sleeping so we are okay anyway. 1535 if (shouldLog) { 1536 mLogger.logScheduleUidIdle1(uidRec.getUid(), 1537 mConstants.BACKGROUND_SETTLE_TIME); 1538 } 1539 mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, 1540 mConstants.BACKGROUND_SETTLE_TIME); // XXX 1541 } 1542 } 1543 if (uidRec.isIdle() && !uidRec.isSetIdle()) { 1544 uidChange |= UidRecord.CHANGE_IDLE; 1545 if (uidRec.getSetProcState() != PROCESS_STATE_NONEXISTENT) { 1546 // don't stop the bg services if it's just started. 1547 becameIdle.add(uidRec); 1548 } 1549 } 1550 } else { 1551 if (uidRec.isIdle()) { 1552 uidChange |= UidRecord.CHANGE_ACTIVE; 1553 EventLogTags.writeAmUidActive(uidRec.getUid()); 1554 uidRec.setIdle(false); 1555 } 1556 uidRec.setLastBackgroundTime(0); 1557 uidRec.setLastIdleTime(0); 1558 if (shouldLog) { 1559 mLogger.logClearLastBackgroundTime(uidRec.getUid()); 1560 } 1561 } 1562 final boolean wasCached = uidRec.getSetProcState() 1563 > ActivityManager.PROCESS_STATE_RECEIVER; 1564 final boolean isCached = uidRec.getCurProcState() 1565 > ActivityManager.PROCESS_STATE_RECEIVER; 1566 if (wasCached != isCached 1567 || uidRec.getSetProcState() == PROCESS_STATE_NONEXISTENT) { 1568 uidChange |= isCached ? UidRecord.CHANGE_CACHED : 1569 UidRecord.CHANGE_UNCACHED; 1570 } 1571 if (uidRec.getSetCapability() != uidRec.getCurCapability()) { 1572 uidChange |= UidRecord.CHANGE_CAPABILITY; 1573 } 1574 if (uidRec.getSetProcState() != uidRec.getCurProcState()) { 1575 uidChange |= UidRecord.CHANGE_PROCSTATE; 1576 } 1577 if (uidRec.getProcAdjChanged()) { 1578 uidChange |= UidRecord.CHANGE_PROCADJ; 1579 } 1580 int oldProcState = uidRec.getSetProcState(); 1581 int oldCapability = uidRec.getSetCapability(); 1582 uidRec.setSetProcState(uidRec.getCurProcState()); 1583 uidRec.setSetCapability(uidRec.getCurCapability()); 1584 uidRec.setSetAllowListed(uidRec.isCurAllowListed()); 1585 uidRec.setSetIdle(uidRec.isIdle()); 1586 uidRec.clearProcAdjChanged(); 1587 if (shouldLog 1588 && ((uidRec.getSetProcState() != oldProcState) 1589 || (uidRec.getSetCapability() != oldCapability))) { 1590 int flags = 0; 1591 if (uidRec.isSetAllowListed()) { 1592 flags |= 1; 1593 } 1594 mLogger.logUidStateChanged(uidRec.getUid(), 1595 uidRec.getSetProcState(), oldProcState, 1596 uidRec.getSetCapability(), oldCapability, 1597 flags); 1598 } 1599 if ((uidChange & UidRecord.CHANGE_PROCSTATE) != 0 1600 || (uidChange & UidRecord.CHANGE_CAPABILITY) != 0) { 1601 mService.mAtmInternal.onUidProcStateChanged( 1602 uidRec.getUid(), uidRec.getSetProcState()); 1603 } 1604 if (uidChange != 0) { 1605 mService.enqueueUidChangeLocked(uidRec, -1, uidChange); 1606 } 1607 if ((uidChange & UidRecord.CHANGE_PROCSTATE) != 0 1608 || (uidChange & UidRecord.CHANGE_CAPABILITY) != 0) { 1609 mService.noteUidProcessState(uidRec.getUid(), uidRec.getCurProcState(), 1610 uidRec.getCurCapability()); 1611 } 1612 if (uidRec.hasForegroundServices()) { 1613 mService.mServices.foregroundServiceProcStateChangedLocked(uidRec); 1614 } 1615 } 1616 } 1617 mService.mInternal.deletePendingTopUid(uidRec.getUid(), nowElapsed); 1618 } 1619 if (mService.mLocalPowerManager != null) { 1620 mService.mLocalPowerManager.finishUidChanges(); 1621 } 1622 1623 int size = becameIdle.size(); 1624 if (size > 0) { 1625 // If we have any new uids that became idle this time, we need to make sure 1626 // they aren't left with running services. 1627 for (int i = size - 1; i >= 0; i--) { 1628 mService.mServices.stopInBackgroundLocked(becameIdle.get(i).getUid()); 1629 } 1630 } 1631 } 1632 1633 /** 1634 * Return true if we should kill excessive cached/empty processes. 1635 */ shouldKillExcessiveProcesses(long nowUptime)1636 private boolean shouldKillExcessiveProcesses(long nowUptime) { 1637 final long lastUserUnlockingUptime = mService.mUserController.getLastUserUnlockingUptime(); 1638 1639 if (lastUserUnlockingUptime == 0) { 1640 // No users have been unlocked. 1641 return !mConstants.mNoKillCachedProcessesUntilBootCompleted; 1642 } 1643 final long noKillCachedProcessesPostBootCompletedDurationMillis = 1644 mConstants.mNoKillCachedProcessesPostBootCompletedDurationMillis; 1645 if ((lastUserUnlockingUptime + noKillCachedProcessesPostBootCompletedDurationMillis) 1646 > nowUptime) { 1647 return false; 1648 } 1649 return true; 1650 } 1651 1652 protected final ComputeOomAdjWindowCallback mTmpComputeOomAdjWindowCallback = 1653 new ComputeOomAdjWindowCallback(); 1654 1655 /** These methods are called inline during computeOomAdjLSP(), on the same thread */ 1656 final class ComputeOomAdjWindowCallback 1657 implements WindowProcessController.ComputeOomAdjCallback { 1658 1659 ProcessRecord app; 1660 int adj; 1661 boolean foregroundActivities; 1662 boolean mHasVisibleActivities; 1663 int procState; 1664 int schedGroup; 1665 int appUid; 1666 int logUid; 1667 int processStateCurTop; 1668 String mAdjType; 1669 ProcessStateRecord mState; 1670 initialize(ProcessRecord app, int adj, boolean foregroundActivities, boolean hasVisibleActivities, int procState, int schedGroup, int appUid, int logUid, int processStateCurTop)1671 void initialize(ProcessRecord app, int adj, boolean foregroundActivities, 1672 boolean hasVisibleActivities, int procState, int schedGroup, int appUid, 1673 int logUid, int processStateCurTop) { 1674 this.app = app; 1675 this.adj = adj; 1676 this.foregroundActivities = foregroundActivities; 1677 this.mHasVisibleActivities = hasVisibleActivities; 1678 this.procState = procState; 1679 this.schedGroup = schedGroup; 1680 this.appUid = appUid; 1681 this.logUid = logUid; 1682 this.processStateCurTop = processStateCurTop; 1683 mAdjType = app.mState.getAdjType(); 1684 this.mState = app.mState; 1685 } 1686 1687 @Override onVisibleActivity()1688 public void onVisibleActivity() { 1689 // App has a visible activity; only upgrade adjustment. 1690 if (adj > VISIBLE_APP_ADJ) { 1691 adj = VISIBLE_APP_ADJ; 1692 mAdjType = "vis-activity"; 1693 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 1694 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to vis-activity: " + app); 1695 } 1696 } 1697 if (procState > processStateCurTop) { 1698 procState = processStateCurTop; 1699 mAdjType = "vis-activity"; 1700 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 1701 reportOomAdjMessageLocked(TAG_OOM_ADJ, 1702 "Raise procstate to vis-activity (top): " + app); 1703 } 1704 } 1705 if (schedGroup < SCHED_GROUP_DEFAULT) { 1706 schedGroup = SCHED_GROUP_DEFAULT; 1707 } 1708 foregroundActivities = true; 1709 mHasVisibleActivities = true; 1710 } 1711 1712 @Override onPausedActivity()1713 public void onPausedActivity() { 1714 if (adj > PERCEPTIBLE_APP_ADJ) { 1715 adj = PERCEPTIBLE_APP_ADJ; 1716 mAdjType = "pause-activity"; 1717 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 1718 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to pause-activity: " + app); 1719 } 1720 } 1721 if (procState > processStateCurTop) { 1722 procState = processStateCurTop; 1723 mAdjType = "pause-activity"; 1724 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 1725 reportOomAdjMessageLocked(TAG_OOM_ADJ, 1726 "Raise procstate to pause-activity (top): " + app); 1727 } 1728 } 1729 if (schedGroup < SCHED_GROUP_DEFAULT) { 1730 schedGroup = SCHED_GROUP_DEFAULT; 1731 } 1732 foregroundActivities = true; 1733 mHasVisibleActivities = false; 1734 } 1735 1736 @Override onStoppingActivity(boolean finishing)1737 public void onStoppingActivity(boolean finishing) { 1738 if (adj > PERCEPTIBLE_APP_ADJ) { 1739 adj = PERCEPTIBLE_APP_ADJ; 1740 mAdjType = "stop-activity"; 1741 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 1742 reportOomAdjMessageLocked(TAG_OOM_ADJ, 1743 "Raise adj to stop-activity: " + app); 1744 } 1745 } 1746 1747 // For the process state, we will at this point consider the process to be cached. It 1748 // will be cached either as an activity or empty depending on whether the activity is 1749 // finishing. We do this so that we can treat the process as cached for purposes of 1750 // memory trimming (determining current memory level, trim command to send to process) 1751 // since there can be an arbitrary number of stopping processes and they should soon all 1752 // go into the cached state. 1753 if (!finishing) { 1754 if (procState > PROCESS_STATE_LAST_ACTIVITY) { 1755 procState = PROCESS_STATE_LAST_ACTIVITY; 1756 mAdjType = "stop-activity"; 1757 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 1758 reportOomAdjMessageLocked(TAG_OOM_ADJ, 1759 "Raise procstate to stop-activity: " + app); 1760 } 1761 } 1762 } 1763 foregroundActivities = true; 1764 mHasVisibleActivities = false; 1765 } 1766 1767 @Override onOtherActivity()1768 public void onOtherActivity() { 1769 if (procState > PROCESS_STATE_CACHED_ACTIVITY) { 1770 procState = PROCESS_STATE_CACHED_ACTIVITY; 1771 mAdjType = "cch-act"; 1772 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 1773 reportOomAdjMessageLocked(TAG_OOM_ADJ, 1774 "Raise procstate to cached activity: " + app); 1775 } 1776 } 1777 mHasVisibleActivities = false; 1778 } 1779 } 1780 isScreenOnOrAnimatingLocked(ProcessStateRecord state)1781 private boolean isScreenOnOrAnimatingLocked(ProcessStateRecord state) { 1782 return mService.mWakefulness.get() == PowerManagerInternal.WAKEFULNESS_AWAKE 1783 || state.isRunningRemoteAnimation(); 1784 } 1785 1786 @GuardedBy({"mService", "mProcLock"}) computeOomAdjLSP(ProcessRecord app, int cachedAdj, ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval, boolean computeClients, int oomAdjReason, boolean couldRecurse)1787 protected boolean computeOomAdjLSP(ProcessRecord app, int cachedAdj, 1788 ProcessRecord topApp, boolean doingAll, long now, boolean cycleReEval, 1789 boolean computeClients, int oomAdjReason, boolean couldRecurse) { 1790 final ProcessStateRecord state = app.mState; 1791 if (couldRecurse) { 1792 if (mAdjSeq == state.getAdjSeq()) { 1793 if (state.getAdjSeq() == state.getCompletedAdjSeq()) { 1794 // This adjustment has already been computed successfully. 1795 return false; 1796 } else { 1797 // The process is being computed, so there is a cycle. We cannot 1798 // rely on this process's state. 1799 state.setContainsCycle(true); 1800 mProcessesInCycle.add(app); 1801 1802 return false; 1803 } 1804 } 1805 } 1806 1807 int prevAppAdj = getInitialAdj(app); 1808 int prevProcState = getInitialProcState(app); 1809 int prevCapability = getInitialCapability(app); 1810 1811 // Remove any follow up update this process might have. It will be rescheduled if still 1812 // needed. 1813 app.mState.setFollowupUpdateUptimeMs(NO_FOLLOW_UP_TIME); 1814 1815 if (app.getThread() == null) { 1816 state.setAdjSeq(mAdjSeq); 1817 state.setCurrentSchedulingGroup(SCHED_GROUP_BACKGROUND); 1818 state.setCurProcState(PROCESS_STATE_CACHED_EMPTY); 1819 state.setCurRawProcState(PROCESS_STATE_CACHED_EMPTY); 1820 state.setCurAdj(CACHED_APP_MAX_ADJ); 1821 state.setCurRawAdj(CACHED_APP_MAX_ADJ); 1822 state.setCompletedAdjSeq(state.getAdjSeq()); 1823 state.setCurCapability(PROCESS_CAPABILITY_NONE); 1824 return false; 1825 } 1826 1827 state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN); 1828 state.setAdjSource(null); 1829 state.setAdjTarget(null); 1830 if (!couldRecurse || !cycleReEval) { 1831 // Don't reset this flag when doing cycles re-evaluation. 1832 state.setNoKillOnBgRestrictedAndIdle(false); 1833 // If this UID is currently allowlisted, it should not be frozen. 1834 final UidRecord uidRec = app.getUidRecord(); 1835 app.mOptRecord.setShouldNotFreeze(uidRec != null && uidRec.isCurAllowListed()); 1836 } 1837 1838 final int appUid = app.info.uid; 1839 final int logUid = mService.mCurOomAdjUid; 1840 1841 final ProcessServiceRecord psr = app.mServices; 1842 1843 if (state.getMaxAdj() <= FOREGROUND_APP_ADJ) { 1844 // The max adjustment doesn't allow this app to be anything 1845 // below foreground, so it is not worth doing work for it. 1846 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 1847 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making fixed: " + app); 1848 } 1849 state.setAdjType("fixed"); 1850 state.setAdjSeq(mAdjSeq); 1851 state.setCurRawAdj(state.getMaxAdj()); 1852 state.setHasForegroundActivities(false); 1853 state.setCurrentSchedulingGroup(SCHED_GROUP_DEFAULT); 1854 state.setCurCapability(PROCESS_CAPABILITY_ALL); // BFSL allowed 1855 state.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT); 1856 // System processes can do UI, and when they do we want to have 1857 // them trim their memory after the user leaves the UI. To 1858 // facilitate this, here we need to determine whether or not it 1859 // is currently showing UI. 1860 state.setSystemNoUi(true); 1861 if (app == topApp) { 1862 state.setSystemNoUi(false); 1863 state.setCurrentSchedulingGroup(SCHED_GROUP_TOP_APP); 1864 state.setAdjType("pers-top-activity"); 1865 } else if (state.hasTopUi()) { 1866 // sched group/proc state adjustment is below 1867 state.setSystemNoUi(false); 1868 state.setAdjType("pers-top-ui"); 1869 } else if (state.getCachedHasVisibleActivities()) { 1870 state.setSystemNoUi(false); 1871 } 1872 if (!state.isSystemNoUi()) { 1873 if (isScreenOnOrAnimatingLocked(state)) { 1874 // screen on or animating, promote UI 1875 state.setCurProcState(ActivityManager.PROCESS_STATE_PERSISTENT_UI); 1876 state.setCurrentSchedulingGroup(SCHED_GROUP_TOP_APP); 1877 } else if (!app.getWindowProcessController().isShowingUiWhileDozing()) { 1878 // screen off, restrict UI scheduling 1879 state.setCurProcState(PROCESS_STATE_BOUND_FOREGROUND_SERVICE); 1880 state.setCurrentSchedulingGroup(SCHED_GROUP_RESTRICTED); 1881 } 1882 } 1883 state.setCurRawProcState(state.getCurProcState()); 1884 state.setCurAdj(state.getMaxAdj()); 1885 state.setCompletedAdjSeq(state.getAdjSeq()); 1886 // if curAdj is less than prevAppAdj, then this process was promoted 1887 return state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState; 1888 } 1889 1890 state.setSystemNoUi(false); 1891 1892 final int PROCESS_STATE_CUR_TOP = mProcessStateCurTop; 1893 1894 // Determine the importance of the process, starting with most 1895 // important to least, and assign an appropriate OOM adjustment. 1896 int adj; 1897 int schedGroup; 1898 int procState; 1899 int capability = cycleReEval ? getInitialCapability(app) : 0; 1900 1901 boolean foregroundActivities = false; 1902 boolean hasVisibleActivities = false; 1903 if (app == topApp && PROCESS_STATE_CUR_TOP == PROCESS_STATE_TOP) { 1904 // The last app on the list is the foreground app. 1905 adj = FOREGROUND_APP_ADJ; 1906 if (mService.mAtmInternal.useTopSchedGroupForTopProcess()) { 1907 schedGroup = SCHED_GROUP_TOP_APP; 1908 state.setAdjType("top-activity"); 1909 } else { 1910 // Demote the scheduling group to avoid CPU contention if there is another more 1911 // important process which also uses top-app, such as if SystemUI is animating. 1912 schedGroup = SCHED_GROUP_DEFAULT; 1913 state.setAdjType("intermediate-top-activity"); 1914 } 1915 foregroundActivities = true; 1916 hasVisibleActivities = true; 1917 procState = PROCESS_STATE_TOP; 1918 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 1919 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top: " + app); 1920 } 1921 } else if (state.isRunningRemoteAnimation()) { 1922 adj = VISIBLE_APP_ADJ; 1923 schedGroup = SCHED_GROUP_TOP_APP; 1924 state.setAdjType("running-remote-anim"); 1925 procState = PROCESS_STATE_CUR_TOP; 1926 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 1927 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making running remote anim: " + app); 1928 } 1929 } else if (app.getActiveInstrumentation() != null) { 1930 // Don't want to kill running instrumentation. 1931 adj = FOREGROUND_APP_ADJ; 1932 schedGroup = SCHED_GROUP_DEFAULT; 1933 state.setAdjType("instrumentation"); 1934 procState = PROCESS_STATE_FOREGROUND_SERVICE; 1935 capability |= PROCESS_CAPABILITY_BFSL; 1936 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 1937 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making instrumentation: " + app); 1938 } 1939 } else if (state.getCachedIsReceivingBroadcast(mTmpSchedGroup)) { 1940 // An app that is currently receiving a broadcast also 1941 // counts as being in the foreground for OOM killer purposes. 1942 // It's placed in a sched group based on the nature of the 1943 // broadcast as reflected by which queue it's active in. 1944 adj = FOREGROUND_APP_ADJ; 1945 schedGroup = mTmpSchedGroup[0]; 1946 state.setAdjType("broadcast"); 1947 procState = ActivityManager.PROCESS_STATE_RECEIVER; 1948 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 1949 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making broadcast: " + app); 1950 } 1951 } else if (psr.numberOfExecutingServices() > 0) { 1952 // An app that is currently executing a service callback also 1953 // counts as being in the foreground. 1954 adj = FOREGROUND_APP_ADJ; 1955 schedGroup = psr.shouldExecServicesFg() 1956 ? SCHED_GROUP_DEFAULT : SCHED_GROUP_BACKGROUND; 1957 state.setAdjType("exec-service"); 1958 procState = PROCESS_STATE_SERVICE; 1959 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 1960 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making exec-service: " + app); 1961 } 1962 } else if (app == topApp) { 1963 adj = FOREGROUND_APP_ADJ; 1964 schedGroup = SCHED_GROUP_BACKGROUND; 1965 state.setAdjType("top-sleeping"); 1966 foregroundActivities = true; 1967 procState = PROCESS_STATE_CUR_TOP; 1968 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 1969 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making top (sleeping): " + app); 1970 } 1971 } else { 1972 // As far as we know the process is empty. We may change our mind later. 1973 schedGroup = SCHED_GROUP_BACKGROUND; 1974 // At this point we don't actually know the adjustment. Use the cached adj 1975 // value that the caller wants us to. 1976 adj = cachedAdj; 1977 procState = PROCESS_STATE_CACHED_EMPTY; 1978 if (!couldRecurse || !state.containsCycle()) { 1979 state.setAdjType("cch-empty"); 1980 } 1981 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 1982 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Making empty: " + app); 1983 } 1984 } 1985 1986 // Examine all activities if not already foreground. 1987 if (!foregroundActivities && state.getCachedHasActivities()) { 1988 state.computeOomAdjFromActivitiesIfNecessary(mTmpComputeOomAdjWindowCallback, 1989 adj, foregroundActivities, hasVisibleActivities, procState, schedGroup, 1990 appUid, logUid, PROCESS_STATE_CUR_TOP); 1991 1992 adj = state.getCachedAdj(); 1993 foregroundActivities = state.getCachedForegroundActivities(); 1994 hasVisibleActivities = state.getCachedHasVisibleActivities(); 1995 procState = state.getCachedProcState(); 1996 schedGroup = state.getCachedSchedGroup(); 1997 state.setAdjType(state.getCachedAdjType()); 1998 } 1999 2000 if (procState > PROCESS_STATE_CACHED_RECENT && state.getCachedHasRecentTasks()) { 2001 procState = PROCESS_STATE_CACHED_RECENT; 2002 state.setAdjType("cch-rec"); 2003 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2004 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to cached recent: " + app); 2005 } 2006 } 2007 2008 int capabilityFromFGS = 0; // capability from foreground service. 2009 2010 final boolean hasForegroundServices = psr.hasForegroundServices(); 2011 final boolean hasNonShortForegroundServices = psr.hasNonShortForegroundServices(); 2012 final boolean hasShortForegroundServices = hasForegroundServices 2013 && !psr.areAllShortForegroundServicesProcstateTimedOut(now); 2014 2015 // Adjust for FGS or "has-overlay-ui". 2016 if (adj > PERCEPTIBLE_APP_ADJ 2017 || procState > PROCESS_STATE_FOREGROUND_SERVICE) { 2018 String adjType = null; 2019 int newAdj = 0; 2020 int newProcState = 0; 2021 2022 if (hasForegroundServices && hasNonShortForegroundServices) { 2023 // For regular (non-short) FGS. 2024 adjType = "fg-service"; 2025 newAdj = PERCEPTIBLE_APP_ADJ; 2026 newProcState = PROCESS_STATE_FOREGROUND_SERVICE; 2027 capabilityFromFGS |= PROCESS_CAPABILITY_BFSL; 2028 2029 } else if (hasShortForegroundServices) { 2030 2031 // For short FGS. 2032 adjType = "fg-service-short"; 2033 2034 // We use MEDIUM_APP_ADJ + 1 so we can tell apart EJ 2035 // (which uses MEDIUM_APP_ADJ + 1) 2036 // from short-FGS. 2037 // (We use +1 and +2, not +0 and +1, to be consistent with the following 2038 // RECENT_FOREGROUND_APP_ADJ tweak) 2039 newAdj = PERCEPTIBLE_MEDIUM_APP_ADJ + 1; 2040 2041 // We give the FGS procstate, but not PROCESS_CAPABILITY_BFSL, so 2042 // short-fgs can't start FGS from the background. 2043 newProcState = PROCESS_STATE_FOREGROUND_SERVICE; 2044 2045 } else if (state.hasOverlayUi()) { 2046 adjType = "has-overlay-ui"; 2047 newAdj = PERCEPTIBLE_APP_ADJ; 2048 newProcState = PROCESS_STATE_IMPORTANT_FOREGROUND; 2049 } 2050 2051 if (adjType != null) { 2052 adj = newAdj; 2053 procState = newProcState; 2054 state.setAdjType(adjType); 2055 schedGroup = SCHED_GROUP_DEFAULT; 2056 2057 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2058 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType + ": " 2059 + app + " "); 2060 } 2061 } 2062 } 2063 2064 // If the app was recently in the foreground and moved to a foreground service status, 2065 // allow it to get a higher rank in memory for some time, compared to other foreground 2066 // services so that it can finish performing any persistence/processing of in-memory state. 2067 if (psr.hasForegroundServices() && adj > PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ 2068 && (state.getLastTopTime() + mConstants.TOP_TO_FGS_GRACE_DURATION > now 2069 || state.getSetProcState() <= PROCESS_STATE_TOP)) { 2070 if (psr.hasNonShortForegroundServices()) { 2071 adj = PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ; 2072 state.setAdjType("fg-service-act"); 2073 } else { 2074 // For short-service FGS, we +1 the value, so we'll be able to detect it in 2075 // various dashboards. 2076 adj = PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 1; 2077 state.setAdjType("fg-service-short-act"); 2078 } 2079 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2080 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to recent fg: " + app); 2081 } 2082 maybeSetProcessFollowUpUpdateLocked(app, 2083 state.getLastTopTime() + mConstants.TOP_TO_FGS_GRACE_DURATION, now); 2084 } 2085 2086 // If the app was recently in the foreground and has expedited jobs running, 2087 // allow it to get a higher rank in memory for some time, compared to other EJS and even 2088 // foreground services so that it can finish performing any persistence/processing of 2089 // in-memory state. 2090 if (psr.hasTopStartedAlmostPerceptibleServices() 2091 && (adj > PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 2) 2092 && (state.getLastTopTime() 2093 + mConstants.TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION > now 2094 || state.getSetProcState() <= PROCESS_STATE_TOP)) { 2095 // For EJ, we +2 the value, so we'll be able to detect it in 2096 // various dashboards. 2097 adj = PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ + 2; 2098 // This shall henceforth be called the "EJ" exemption, despite utilizing the 2099 // ALMOST_PERCEPTIBLE flag to work. 2100 state.setAdjType("top-ej-act"); 2101 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2102 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to recent fg for EJ: " + app); 2103 } 2104 maybeSetProcessFollowUpUpdateLocked(app, 2105 state.getLastTopTime() + mConstants.TOP_TO_ALMOST_PERCEPTIBLE_GRACE_DURATION, 2106 now); 2107 } 2108 2109 if (adj > PERCEPTIBLE_APP_ADJ 2110 || procState > PROCESS_STATE_TRANSIENT_BACKGROUND) { 2111 if (state.getForcingToImportant() != null) { 2112 // This is currently used for toasts... they are not interactive, and 2113 // we don't want them to cause the app to become fully foreground (and 2114 // thus out of background check), so we yes the best background level we can. 2115 adj = PERCEPTIBLE_APP_ADJ; 2116 procState = PROCESS_STATE_TRANSIENT_BACKGROUND; 2117 state.setAdjType("force-imp"); 2118 state.setAdjSource(state.getForcingToImportant()); 2119 schedGroup = SCHED_GROUP_DEFAULT; 2120 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2121 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to force imp: " + app); 2122 } 2123 } 2124 } 2125 2126 if (state.getCachedIsHeavyWeight()) { 2127 if (adj > HEAVY_WEIGHT_APP_ADJ) { 2128 // We don't want to kill the current heavy-weight process. 2129 adj = HEAVY_WEIGHT_APP_ADJ; 2130 schedGroup = SCHED_GROUP_BACKGROUND; 2131 state.setAdjType("heavy"); 2132 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2133 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to heavy: " + app); 2134 } 2135 } 2136 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) { 2137 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT; 2138 state.setAdjType("heavy"); 2139 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2140 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to heavy: " + app); 2141 } 2142 } 2143 } 2144 2145 if (state.getCachedIsHomeProcess()) { 2146 if (adj > HOME_APP_ADJ) { 2147 // This process is hosting what we currently consider to be the 2148 // home app, so we don't want to let it go into the background. 2149 adj = HOME_APP_ADJ; 2150 schedGroup = SCHED_GROUP_BACKGROUND; 2151 state.setAdjType("home"); 2152 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2153 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to home: " + app); 2154 } 2155 } 2156 if (procState > ActivityManager.PROCESS_STATE_HOME) { 2157 procState = ActivityManager.PROCESS_STATE_HOME; 2158 state.setAdjType("home"); 2159 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2160 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to home: " + app); 2161 } 2162 } 2163 } 2164 if (state.getCachedIsPreviousProcess() && state.getCachedHasActivities()) { 2165 // This was the previous process that showed UI to the user. We want to 2166 // try to keep it around more aggressively, to give a good experience 2167 // around switching between two apps. However, we don't want to keep the 2168 // process in this privileged state indefinitely. Eventually, allow the 2169 // app to be demoted to cached. 2170 if (procState >= PROCESS_STATE_LAST_ACTIVITY 2171 && state.getSetProcState() == PROCESS_STATE_LAST_ACTIVITY 2172 && (state.getLastStateTime() + mConstants.MAX_PREVIOUS_TIME) <= now) { 2173 procState = PROCESS_STATE_LAST_ACTIVITY; 2174 schedGroup = SCHED_GROUP_BACKGROUND; 2175 state.setAdjType("previous-expired"); 2176 adj = CACHED_APP_MIN_ADJ; 2177 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2178 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Expire prev adj: " + app); 2179 } 2180 } else { 2181 if (adj > PREVIOUS_APP_ADJ) { 2182 adj = PREVIOUS_APP_ADJ; 2183 schedGroup = SCHED_GROUP_BACKGROUND; 2184 state.setAdjType("previous"); 2185 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2186 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to prev: " + app); 2187 } 2188 } 2189 if (procState > PROCESS_STATE_LAST_ACTIVITY) { 2190 procState = PROCESS_STATE_LAST_ACTIVITY; 2191 state.setAdjType("previous"); 2192 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2193 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to prev: " + app); 2194 } 2195 } 2196 final long lastStateTime; 2197 if (state.getSetProcState() == PROCESS_STATE_LAST_ACTIVITY) { 2198 lastStateTime = state.getLastStateTime(); 2199 } else { 2200 lastStateTime = now; 2201 } 2202 maybeSetProcessFollowUpUpdateLocked(app, 2203 lastStateTime + mConstants.MAX_PREVIOUS_TIME, now); 2204 } 2205 } 2206 2207 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj 2208 + " reason=" + state.getAdjType()); 2209 2210 // By default, we use the computed adjustment. It may be changed if 2211 // there are applications dependent on our services or providers, but 2212 // this gives us a baseline and makes sure we don't get into an 2213 // infinite recursion. If we're re-evaluating due to cycles, use the previously computed 2214 // values. 2215 if (cycleReEval) { 2216 procState = Math.min(procState, state.getCurRawProcState()); 2217 adj = Math.min(adj, state.getCurRawAdj()); 2218 schedGroup = Math.max(schedGroup, state.getCurrentSchedulingGroup()); 2219 } 2220 state.setCurRawAdj(adj); 2221 state.setCurRawProcState(procState); 2222 2223 state.setHasStartedServices(false); 2224 state.setAdjSeq(mAdjSeq); 2225 2226 final BackupRecord backupTarget = mService.mBackupTargets.get(app.userId); 2227 if (backupTarget != null && app == backupTarget.app) { 2228 // If possible we want to avoid killing apps while they're being backed up 2229 if (adj > BACKUP_APP_ADJ) { 2230 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app); 2231 adj = BACKUP_APP_ADJ; 2232 if (procState > PROCESS_STATE_TRANSIENT_BACKGROUND) { 2233 procState = PROCESS_STATE_TRANSIENT_BACKGROUND; 2234 } 2235 state.setAdjType("backup"); 2236 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2237 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise adj to backup: " + app); 2238 } 2239 } 2240 if (procState > ActivityManager.PROCESS_STATE_BACKUP) { 2241 procState = ActivityManager.PROCESS_STATE_BACKUP; 2242 state.setAdjType("backup"); 2243 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2244 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise procstate to backup: " + app); 2245 } 2246 } 2247 } 2248 2249 state.setCurBoundByNonBgRestrictedApp(getInitialIsCurBoundByNonBgRestrictedApp(app)); 2250 2251 state.setScheduleLikeTopApp(false); 2252 2253 for (int is = psr.numberOfRunningServices() - 1; 2254 is >= 0 && (adj > FOREGROUND_APP_ADJ 2255 || schedGroup == SCHED_GROUP_BACKGROUND 2256 || procState > PROCESS_STATE_TOP); 2257 is--) { 2258 ServiceRecord s = psr.getRunningServiceAt(is); 2259 if (s.startRequested) { 2260 state.setHasStartedServices(true); 2261 if (procState > PROCESS_STATE_SERVICE) { 2262 procState = PROCESS_STATE_SERVICE; 2263 state.setAdjType("started-services"); 2264 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2265 reportOomAdjMessageLocked(TAG_OOM_ADJ, 2266 "Raise procstate to started service: " + app); 2267 } 2268 } 2269 if (!s.mKeepWarming && state.hasShownUi() && !state.getCachedIsHomeProcess()) { 2270 // If this process has shown some UI, let it immediately 2271 // go to the LRU list because it may be pretty heavy with 2272 // UI stuff. We'll tag it with a label just to help 2273 // debug and understand what is going on. 2274 if (adj > SERVICE_ADJ) { 2275 state.setAdjType("cch-started-ui-services"); 2276 } 2277 } else { 2278 if (s.mKeepWarming 2279 || now < (s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY)) { 2280 // This service has seen some activity within 2281 // recent memory, so we will keep its process ahead 2282 // of the background processes. This does not apply 2283 // to the SDK sandbox process since it should never 2284 // be more important than its corresponding app. 2285 if (!app.isSdkSandbox && adj > SERVICE_ADJ) { 2286 adj = SERVICE_ADJ; 2287 state.setAdjType("started-services"); 2288 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2289 reportOomAdjMessageLocked(TAG_OOM_ADJ, 2290 "Raise adj to started service: " + app); 2291 } 2292 maybeSetProcessFollowUpUpdateLocked(app, 2293 s.lastActivity + mConstants.MAX_SERVICE_INACTIVITY, now); 2294 } 2295 } 2296 // If we have let the service slide into the background 2297 // state, still have some text describing what it is doing 2298 // even though the service no longer has an impact. 2299 if (adj > SERVICE_ADJ) { 2300 state.setAdjType("cch-started-services"); 2301 } 2302 } 2303 } 2304 2305 if (s.isForeground) { 2306 final int fgsType = s.foregroundServiceType; 2307 if (s.isFgsAllowedWiu_forCapabilities()) { 2308 capabilityFromFGS |= 2309 (fgsType & FOREGROUND_SERVICE_TYPE_LOCATION) 2310 != 0 ? PROCESS_CAPABILITY_FOREGROUND_LOCATION : 0; 2311 2312 if (roForegroundAudioControl()) { // flag check 2313 // TODO(b/335373208) - revisit restriction of FOREGROUND_AUDIO_CONTROL 2314 // when it can be limited to specific FGS types 2315 capabilityFromFGS |= PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL; 2316 } 2317 2318 final boolean enabled = state.getCachedCompatChange( 2319 CACHED_COMPAT_CHANGE_CAMERA_MICROPHONE_CAPABILITY); 2320 if (enabled) { 2321 capabilityFromFGS |= 2322 (fgsType & FOREGROUND_SERVICE_TYPE_CAMERA) 2323 != 0 ? PROCESS_CAPABILITY_FOREGROUND_CAMERA : 0; 2324 capabilityFromFGS |= 2325 (fgsType & FOREGROUND_SERVICE_TYPE_MICROPHONE) 2326 != 0 ? PROCESS_CAPABILITY_FOREGROUND_MICROPHONE : 0; 2327 } else { 2328 capabilityFromFGS |= PROCESS_CAPABILITY_FOREGROUND_CAMERA 2329 | PROCESS_CAPABILITY_FOREGROUND_MICROPHONE; 2330 } 2331 } 2332 } 2333 2334 if (!couldRecurse) { 2335 // We're entering recursive functions below, if we're told it's not a recursive 2336 // loop, abort here. 2337 continue; 2338 } 2339 2340 2341 state.setCurRawAdj(adj); 2342 state.setCurRawProcState(procState); 2343 state.setCurrentSchedulingGroup(schedGroup); 2344 state.setCurCapability(capability); 2345 2346 ArrayMap<IBinder, ArrayList<ConnectionRecord>> serviceConnections = s.getConnections(); 2347 for (int conni = serviceConnections.size() - 1; 2348 conni >= 0 && (adj > FOREGROUND_APP_ADJ 2349 || schedGroup == SCHED_GROUP_BACKGROUND 2350 || procState > PROCESS_STATE_TOP); 2351 conni--) { 2352 ArrayList<ConnectionRecord> clist = serviceConnections.valueAt(conni); 2353 for (int i = 0; 2354 i < clist.size() && (adj > FOREGROUND_APP_ADJ 2355 || schedGroup == SCHED_GROUP_BACKGROUND 2356 || procState > PROCESS_STATE_TOP); 2357 i++) { 2358 // XXX should compute this based on the max of 2359 // all connected clients. 2360 ConnectionRecord cr = clist.get(i); 2361 if (cr.binding.client == app) { 2362 // Binding to oneself is not interesting. 2363 continue; 2364 } 2365 2366 computeServiceHostOomAdjLSP(cr, app, cr.binding.client, now, topApp, doingAll, 2367 cycleReEval, computeClients, oomAdjReason, cachedAdj, true, false); 2368 2369 adj = state.getCurRawAdj(); 2370 procState = state.getCurRawProcState(); 2371 schedGroup = state.getCurrentSchedulingGroup(); 2372 capability = state.getCurCapability(); 2373 } 2374 } 2375 } 2376 2377 final ProcessProviderRecord ppr = app.mProviders; 2378 for (int provi = ppr.numberOfProviders() - 1; 2379 provi >= 0 && (adj > FOREGROUND_APP_ADJ 2380 || schedGroup == SCHED_GROUP_BACKGROUND 2381 || procState > PROCESS_STATE_TOP); 2382 provi--) { 2383 ContentProviderRecord cpr = ppr.getProviderAt(provi); 2384 if (couldRecurse) { 2385 // We're entering recursive functions below. 2386 state.setCurRawAdj(adj); 2387 state.setCurRawProcState(procState); 2388 state.setCurrentSchedulingGroup(schedGroup); 2389 state.setCurCapability(capability); 2390 2391 for (int i = cpr.connections.size() - 1; 2392 i >= 0 && (adj > FOREGROUND_APP_ADJ 2393 || schedGroup == SCHED_GROUP_BACKGROUND 2394 || procState > PROCESS_STATE_TOP); 2395 i--) { 2396 ContentProviderConnection conn = cpr.connections.get(i); 2397 ProcessRecord client = conn.client; 2398 computeProviderHostOomAdjLSP(conn, app, client, now, topApp, doingAll, 2399 cycleReEval, computeClients, oomAdjReason, cachedAdj, true, false); 2400 2401 adj = state.getCurRawAdj(); 2402 procState = state.getCurRawProcState(); 2403 schedGroup = state.getCurrentSchedulingGroup(); 2404 capability = state.getCurCapability(); 2405 } 2406 } 2407 // If the provider has external (non-framework) process 2408 // dependencies, ensure that its adjustment is at least 2409 // FOREGROUND_APP_ADJ. 2410 if (cpr.hasExternalProcessHandles()) { 2411 if (adj > FOREGROUND_APP_ADJ) { 2412 adj = FOREGROUND_APP_ADJ; 2413 state.setCurRawAdj(adj); 2414 schedGroup = SCHED_GROUP_DEFAULT; 2415 state.setAdjType("ext-provider"); 2416 state.setAdjTarget(cpr.name); 2417 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2418 reportOomAdjMessageLocked(TAG_OOM_ADJ, 2419 "Raise adj to external provider: " + app); 2420 } 2421 } 2422 if (procState > PROCESS_STATE_IMPORTANT_FOREGROUND) { 2423 procState = PROCESS_STATE_IMPORTANT_FOREGROUND; 2424 state.setCurRawProcState(procState); 2425 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2426 reportOomAdjMessageLocked(TAG_OOM_ADJ, 2427 "Raise procstate to external provider: " + app); 2428 } 2429 } 2430 } 2431 } 2432 2433 if ((ppr.getLastProviderTime() + mConstants.CONTENT_PROVIDER_RETAIN_TIME) > now) { 2434 if (adj > PREVIOUS_APP_ADJ) { 2435 adj = PREVIOUS_APP_ADJ; 2436 schedGroup = SCHED_GROUP_BACKGROUND; 2437 state.setAdjType("recent-provider"); 2438 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2439 reportOomAdjMessageLocked(TAG_OOM_ADJ, 2440 "Raise adj to recent provider: " + app); 2441 } 2442 maybeSetProcessFollowUpUpdateLocked(app, 2443 ppr.getLastProviderTime() + mConstants.CONTENT_PROVIDER_RETAIN_TIME, now); 2444 } 2445 if (procState > PROCESS_STATE_LAST_ACTIVITY) { 2446 procState = PROCESS_STATE_LAST_ACTIVITY; 2447 state.setAdjType("recent-provider"); 2448 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2449 reportOomAdjMessageLocked(TAG_OOM_ADJ, 2450 "Raise procstate to recent provider: " + app); 2451 } 2452 maybeSetProcessFollowUpUpdateLocked(app, 2453 ppr.getLastProviderTime() + mConstants.CONTENT_PROVIDER_RETAIN_TIME, now); 2454 } 2455 } 2456 2457 if (procState >= PROCESS_STATE_CACHED_EMPTY) { 2458 if (psr.hasClientActivities()) { 2459 // This is a cached process, but with client activities. Mark it so. 2460 procState = PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 2461 state.setAdjType("cch-client-act"); 2462 } else if (psr.isTreatedLikeActivity()) { 2463 // This is a cached process, but somebody wants us to treat it like it has 2464 // an activity, okay! 2465 procState = PROCESS_STATE_CACHED_ACTIVITY; 2466 state.setAdjType("cch-as-act"); 2467 } 2468 } 2469 2470 if (adj == SERVICE_ADJ) { 2471 if (doingAll && !cycleReEval) { 2472 state.setServiceB(mNewNumAServiceProcs > (mNumServiceProcs / 3)); 2473 mNewNumServiceProcs++; 2474 if (!state.isServiceB()) { 2475 // This service isn't far enough down on the LRU list to 2476 // normally be a B service, but if we are low on RAM and it 2477 // is large we want to force it down since we would prefer to 2478 // keep launcher over it. 2479 long lastPssOrRss = mService.mAppProfiler.isProfilingPss() 2480 ? app.mProfile.getLastPss() : app.mProfile.getLastRss(); 2481 2482 // RSS is larger than PSS, but the RSS/PSS ratio varies per-process based on how 2483 // many shared pages a process uses. The threshold is increased if the flag for 2484 // reading RSS instead of PSS is enabled. 2485 // 2486 // TODO(b/296454553): Tune the second value so that the relative number of 2487 // service B is similar before/after this flag is enabled. 2488 double thresholdModifier = mService.mAppProfiler.isProfilingPss() 2489 ? 1 : mConstants.PSS_TO_RSS_THRESHOLD_MODIFIER; 2490 double cachedRestoreThreshold = 2491 mProcessList.getCachedRestoreThresholdKb() * thresholdModifier; 2492 2493 if (!mService.mAppProfiler.isLastMemoryLevelNormal() 2494 && lastPssOrRss >= cachedRestoreThreshold) { 2495 state.setServiceHighRam(true); 2496 state.setServiceB(true); 2497 //Slog.i(TAG, "ADJ " + app + " high ram!"); 2498 } else { 2499 mNewNumAServiceProcs++; 2500 //Slog.i(TAG, "ADJ " + app + " not high ram!"); 2501 } 2502 } else { 2503 state.setServiceHighRam(false); 2504 } 2505 } 2506 if (state.isServiceB()) { 2507 adj = SERVICE_B_ADJ; 2508 } 2509 } 2510 2511 state.setCurRawAdj(adj); 2512 adj = psr.modifyRawOomAdj(adj); 2513 if (adj > state.getMaxAdj()) { 2514 adj = state.getMaxAdj(); 2515 if (adj <= PERCEPTIBLE_LOW_APP_ADJ) { 2516 schedGroup = SCHED_GROUP_DEFAULT; 2517 } 2518 } 2519 2520 // Put bound foreground services in a special sched group for additional 2521 // restrictions on screen off 2522 if (procState >= PROCESS_STATE_BOUND_FOREGROUND_SERVICE 2523 && mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE 2524 && !state.shouldScheduleLikeTopApp()) { 2525 if (schedGroup > SCHED_GROUP_RESTRICTED) { 2526 schedGroup = SCHED_GROUP_RESTRICTED; 2527 } 2528 } 2529 2530 // apply capability from FGS. 2531 if (psr.hasForegroundServices()) { 2532 capability |= capabilityFromFGS; 2533 } 2534 2535 capability |= getDefaultCapability(app, procState); 2536 2537 // Procstates below BFGS should never have this capability. 2538 if (procState > PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { 2539 capability &= ~PROCESS_CAPABILITY_BFSL; 2540 } 2541 2542 if (app.isPendingFinishAttach()) { 2543 // If the app is still starting up. We reset the computations to the 2544 // hardcoded values in setAttachingProcessStatesLSP. This ensures that the app keeps 2545 // hard-coded default 'startup' oom scores while starting up. When it finishes startup, 2546 // we'll recompute oom scores based on it's actual hosted compoenents. 2547 setAttachingProcessStatesLSP(app); 2548 state.setAdjSeq(mAdjSeq); 2549 state.setCompletedAdjSeq(state.getAdjSeq()); 2550 return false; 2551 } 2552 2553 // Do final modification to adj. Everything we do between here and applying 2554 // the final setAdj must be done in this function, because we will also use 2555 // it when computing the final cached adj later. Note that we don't need to 2556 // worry about this for max adj above, since max adj will always be used to 2557 // keep it out of the cached vaues. 2558 state.setCurCapability(capability); 2559 state.updateLastInvisibleTime(hasVisibleActivities); 2560 state.setHasForegroundActivities(foregroundActivities); 2561 state.setCompletedAdjSeq(mAdjSeq); 2562 2563 schedGroup = setIntermediateAdjLSP(app, adj, prevAppAdj, schedGroup); 2564 setIntermediateProcStateLSP(app, procState, prevProcState); 2565 setIntermediateSchedGroupLSP(state, schedGroup); 2566 2567 // if curAdj or curProcState improved, then this process was promoted 2568 return state.getCurAdj() < prevAppAdj || state.getCurProcState() < prevProcState 2569 || state.getCurCapability() != prevCapability; 2570 } 2571 2572 /** 2573 * @return The proposed change to the schedGroup. 2574 */ 2575 @GuardedBy({"mService", "mProcLock"}) setIntermediateAdjLSP(ProcessRecord app, int adj, int prevRawAppAdj, int schedGroup)2576 protected int setIntermediateAdjLSP(ProcessRecord app, int adj, int prevRawAppAdj, 2577 int schedGroup) { 2578 final ProcessStateRecord state = app.mState; 2579 state.setCurRawAdj(adj); 2580 2581 adj = app.mServices.modifyRawOomAdj(adj); 2582 if (adj > state.getMaxAdj()) { 2583 adj = state.getMaxAdj(); 2584 if (adj <= PERCEPTIBLE_LOW_APP_ADJ) { 2585 schedGroup = SCHED_GROUP_DEFAULT; 2586 } 2587 } 2588 2589 state.setCurAdj(adj); 2590 2591 return schedGroup; 2592 } 2593 2594 @GuardedBy({"mService", "mProcLock"}) setIntermediateProcStateLSP(ProcessRecord app, int procState, int prevProcState)2595 protected void setIntermediateProcStateLSP(ProcessRecord app, int procState, 2596 int prevProcState) { 2597 final ProcessStateRecord state = app.mState; 2598 state.setCurProcState(procState); 2599 state.setCurRawProcState(procState); 2600 } 2601 2602 @GuardedBy({"mService", "mProcLock"}) setIntermediateSchedGroupLSP(ProcessStateRecord state, int schedGroup)2603 protected void setIntermediateSchedGroupLSP(ProcessStateRecord state, int schedGroup) { 2604 // Put bound foreground services in a special sched group for additional 2605 // restrictions on screen off 2606 if (state.getCurProcState() >= PROCESS_STATE_BOUND_FOREGROUND_SERVICE 2607 && mService.mWakefulness.get() != PowerManagerInternal.WAKEFULNESS_AWAKE 2608 && !state.shouldScheduleLikeTopApp()) { 2609 if (schedGroup > SCHED_GROUP_RESTRICTED) { 2610 schedGroup = SCHED_GROUP_RESTRICTED; 2611 } 2612 } 2613 2614 state.setCurrentSchedulingGroup(schedGroup); 2615 } 2616 2617 @GuardedBy({"mService", "mProcLock"}) computeServiceHostOomAdjLSP(ConnectionRecord cr, ProcessRecord app, ProcessRecord client, long now, ProcessRecord topApp, boolean doingAll, boolean cycleReEval, boolean computeClients, int oomAdjReason, int cachedAdj, boolean couldRecurse, boolean dryRun)2618 public boolean computeServiceHostOomAdjLSP(ConnectionRecord cr, ProcessRecord app, 2619 ProcessRecord client, long now, ProcessRecord topApp, boolean doingAll, 2620 boolean cycleReEval, boolean computeClients, int oomAdjReason, int cachedAdj, 2621 boolean couldRecurse, boolean dryRun) { 2622 if (app.isPendingFinishAttach()) { 2623 // We've set the attaching process state in the computeInitialOomAdjLSP. Skip it here. 2624 return false; 2625 } 2626 2627 final ProcessStateRecord state = app.mState; 2628 ProcessStateRecord cstate = client.mState; 2629 boolean updated = false; 2630 2631 if (couldRecurse) { 2632 if (app.isSdkSandbox && cr.binding.attributedClient != null) { 2633 // For SDK sandboxes, use the attributed client (eg the app that 2634 // requested the sandbox) 2635 client = cr.binding.attributedClient; 2636 cstate = client.mState; 2637 } 2638 if (computeClients) { 2639 computeOomAdjLSP(client, cachedAdj, topApp, doingAll, now, cycleReEval, true, 2640 oomAdjReason, true); 2641 } else { 2642 cstate.setCurRawAdj(cstate.getCurAdj()); 2643 cstate.setCurRawProcState(cstate.getCurProcState()); 2644 } 2645 } 2646 2647 int clientAdj = cstate.getCurRawAdj(); 2648 int clientProcState = cstate.getCurRawProcState(); 2649 2650 final boolean clientIsSystem = clientProcState < PROCESS_STATE_TOP; 2651 2652 int adj = state.getCurRawAdj(); 2653 int procState = state.getCurRawProcState(); 2654 int schedGroup = state.getCurrentSchedulingGroup(); 2655 int capability = state.getCurCapability(); 2656 2657 final int prevRawAdj = adj; 2658 final int prevProcState = procState; 2659 final int prevSchedGroup = schedGroup; 2660 final int prevCapability = capability; 2661 2662 final int appUid = app.info.uid; 2663 final int logUid = mService.mCurOomAdjUid; 2664 2665 if (!dryRun) { 2666 state.setCurBoundByNonBgRestrictedApp(state.isCurBoundByNonBgRestrictedApp() 2667 || cstate.isCurBoundByNonBgRestrictedApp() 2668 || clientProcState <= PROCESS_STATE_BOUND_TOP 2669 || (clientProcState == PROCESS_STATE_FOREGROUND_SERVICE 2670 && !cstate.isBackgroundRestricted())); 2671 } 2672 2673 if (client.mOptRecord.shouldNotFreeze()) { 2674 // Propagate the shouldNotFreeze flag down the bindings. 2675 if (app.mOptRecord.setShouldNotFreeze(true, dryRun)) { 2676 // Bail out early, as we only care about the return value for a dryrun. 2677 return true; 2678 } 2679 } 2680 2681 boolean trackedProcState = false; 2682 2683 // We always propagate PROCESS_CAPABILITY_BFSL over bindings here, 2684 // but, right before actually setting it to the process, 2685 // we check the final procstate, and remove it if the procsate is below BFGS. 2686 capability |= getBfslCapabilityFromClient(client); 2687 2688 if (cr.notHasFlag(Context.BIND_WAIVE_PRIORITY)) { 2689 if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) { 2690 capability |= cstate.getCurCapability(); 2691 } 2692 2693 // If an app has network capability by default 2694 // (by having procstate <= BFGS), then the apps it binds to will get 2695 // elevated to a high enough procstate anyway to get network unless they 2696 // request otherwise, so don't propagate the network capability by default 2697 // in this case unless they explicitly request it. 2698 if ((cstate.getCurCapability() 2699 & PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK) != 0) { 2700 if (clientProcState <= PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { 2701 // This is used to grant network access to Expedited Jobs. 2702 if (cr.hasFlag(Context.BIND_BYPASS_POWER_NETWORK_RESTRICTIONS)) { 2703 capability |= PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK; 2704 } 2705 } else { 2706 capability |= PROCESS_CAPABILITY_POWER_RESTRICTED_NETWORK; 2707 } 2708 } 2709 if ((cstate.getCurCapability() 2710 & PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK) != 0) { 2711 if (clientProcState <= PROCESS_STATE_IMPORTANT_FOREGROUND) { 2712 // This is used to grant network access to User Initiated Jobs. 2713 if (cr.hasFlag(Context.BIND_BYPASS_USER_NETWORK_RESTRICTIONS)) { 2714 capability |= PROCESS_CAPABILITY_USER_RESTRICTED_NETWORK; 2715 } 2716 } 2717 } 2718 2719 // Sandbox should be able to control audio only when bound client 2720 // has this capability. 2721 if ((cstate.getCurCapability() 2722 & PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL) != 0) { 2723 if (app.isSdkSandbox) { 2724 capability |= PROCESS_CAPABILITY_FOREGROUND_AUDIO_CONTROL; 2725 } 2726 } 2727 2728 if (couldRecurse && shouldSkipDueToCycle(app, cstate, procState, adj, cycleReEval)) { 2729 return false; 2730 } 2731 2732 if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) { 2733 // If the other app is cached for any reason, for purposes here 2734 // we are going to consider it empty. The specific cached state 2735 // doesn't propagate except under certain conditions. 2736 clientProcState = PROCESS_STATE_CACHED_EMPTY; 2737 } 2738 String adjType = null; 2739 if (cr.hasFlag(Context.BIND_ALLOW_OOM_MANAGEMENT)) { 2740 // Similar to BIND_WAIVE_PRIORITY, keep it unfrozen. 2741 if (clientAdj < CACHED_APP_MIN_ADJ) { 2742 if (app.mOptRecord.setShouldNotFreeze(true, dryRun)) { 2743 // Bail out early, as we only care about the return value for a dryrun. 2744 return true; 2745 } 2746 } 2747 // Not doing bind OOM management, so treat 2748 // this guy more like a started service. 2749 if (state.hasShownUi() && !state.getCachedIsHomeProcess()) { 2750 // If this process has shown some UI, let it immediately 2751 // go to the LRU list because it may be pretty heavy with 2752 // UI stuff. We'll tag it with a label just to help 2753 // debug and understand what is going on. 2754 if (adj > clientAdj) { 2755 adjType = "cch-bound-ui-services"; 2756 } 2757 2758 if (state.isCached() && dryRun) { 2759 // Bail out early, as we only care about the return value for a dryrun. 2760 return true; 2761 } 2762 2763 clientAdj = adj; 2764 clientProcState = procState; 2765 } else { 2766 if (now >= (cr.binding.service.lastActivity 2767 + mConstants.MAX_SERVICE_INACTIVITY)) { 2768 // This service has not seen activity within 2769 // recent memory, so allow it to drop to the 2770 // LRU list if there is no other reason to keep 2771 // it around. We'll also tag it with a label just 2772 // to help debug and undertand what is going on. 2773 if (adj > clientAdj) { 2774 adjType = "cch-bound-services"; 2775 } 2776 clientAdj = adj; 2777 } 2778 } 2779 } 2780 if (adj > clientAdj) { 2781 // If this process has recently shown UI, and 2782 // the process that is binding to it is less 2783 // important than being visible, then we don't 2784 // care about the binding as much as we care 2785 // about letting this process get into the LRU 2786 // list to be killed and restarted if needed for 2787 // memory. 2788 if (state.hasShownUi() && !state.getCachedIsHomeProcess() 2789 && clientAdj > PERCEPTIBLE_APP_ADJ) { 2790 if (adj >= CACHED_APP_MIN_ADJ) { 2791 adjType = "cch-bound-ui-services"; 2792 } 2793 } else { 2794 int newAdj; 2795 int lbAdj = VISIBLE_APP_ADJ; // lower bound of adj. 2796 if (cr.hasFlag(Context.BIND_ABOVE_CLIENT 2797 | Context.BIND_IMPORTANT)) { 2798 if (clientAdj >= PERSISTENT_SERVICE_ADJ) { 2799 newAdj = clientAdj; 2800 } else { 2801 // make this service persistent 2802 newAdj = PERSISTENT_SERVICE_ADJ; 2803 schedGroup = SCHED_GROUP_DEFAULT; 2804 procState = ActivityManager.PROCESS_STATE_PERSISTENT; 2805 if (!dryRun) { 2806 cr.trackProcState(procState, mAdjSeq); 2807 } 2808 trackedProcState = true; 2809 } 2810 } else if (cr.hasFlag(Context.BIND_NOT_PERCEPTIBLE) 2811 && clientAdj <= PERCEPTIBLE_APP_ADJ 2812 && adj >= (lbAdj = PERCEPTIBLE_LOW_APP_ADJ)) { 2813 newAdj = PERCEPTIBLE_LOW_APP_ADJ; 2814 } else if (cr.hasFlag(Context.BIND_ALMOST_PERCEPTIBLE) 2815 && cr.notHasFlag(Context.BIND_NOT_FOREGROUND) 2816 && clientAdj < PERCEPTIBLE_APP_ADJ 2817 && adj >= (lbAdj = PERCEPTIBLE_APP_ADJ)) { 2818 // This is for user-initiated jobs. 2819 // We use APP_ADJ + 1 here, so we can tell them apart from FGS. 2820 newAdj = PERCEPTIBLE_APP_ADJ + 1; 2821 } else if (cr.hasFlag(Context.BIND_ALMOST_PERCEPTIBLE) 2822 && cr.hasFlag(Context.BIND_NOT_FOREGROUND) 2823 && clientAdj < PERCEPTIBLE_APP_ADJ 2824 && adj >= (lbAdj = (PERCEPTIBLE_MEDIUM_APP_ADJ + 2))) { 2825 // This is for expedited jobs. 2826 // We use MEDIUM_APP_ADJ + 2 here, so we can tell apart 2827 // EJ and short-FGS. 2828 newAdj = PERCEPTIBLE_MEDIUM_APP_ADJ + 2; 2829 } else if (cr.hasFlag(Context.BIND_NOT_VISIBLE) 2830 && clientAdj < PERCEPTIBLE_APP_ADJ 2831 && adj >= (lbAdj = PERCEPTIBLE_APP_ADJ)) { 2832 newAdj = PERCEPTIBLE_APP_ADJ; 2833 } else if (clientAdj >= PERCEPTIBLE_APP_ADJ) { 2834 newAdj = clientAdj; 2835 } else if (cr.hasFlag(BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE) 2836 && clientAdj <= VISIBLE_APP_ADJ 2837 && adj > VISIBLE_APP_ADJ) { 2838 newAdj = VISIBLE_APP_ADJ; 2839 } else { 2840 if (adj > VISIBLE_APP_ADJ) { 2841 // TODO: Is this too limiting for apps bound from TOP? 2842 newAdj = Math.max(clientAdj, lbAdj); 2843 } else { 2844 newAdj = adj; 2845 } 2846 } 2847 2848 if (!cstate.isCached()) { 2849 if (state.isCached() && dryRun) { 2850 // Bail out early, as we only care about the return value for a dryrun. 2851 return true; 2852 } 2853 } 2854 2855 if (adj > newAdj) { 2856 adj = newAdj; 2857 if (state.setCurRawAdj(adj, dryRun)) { 2858 // Bail out early, as we only care about the return value for a dryrun. 2859 } 2860 adjType = "service"; 2861 } 2862 } 2863 } 2864 if (cr.notHasFlag(Context.BIND_NOT_FOREGROUND 2865 | Context.BIND_IMPORTANT_BACKGROUND)) { 2866 // This will treat important bound services identically to 2867 // the top app, which may behave differently than generic 2868 // foreground work. 2869 final int curSchedGroup = cstate.getCurrentSchedulingGroup(); 2870 if (curSchedGroup > schedGroup) { 2871 if (cr.hasFlag(Context.BIND_IMPORTANT)) { 2872 schedGroup = curSchedGroup; 2873 } else { 2874 schedGroup = SCHED_GROUP_DEFAULT; 2875 } 2876 } 2877 if (clientProcState < PROCESS_STATE_TOP) { 2878 // Special handling for above-top states (persistent 2879 // processes). These should not bring the current process 2880 // into the top state, since they are not on top. Instead 2881 // give them the best bound state after that. 2882 if (cr.hasFlag(BIND_TREAT_LIKE_VISIBLE_FOREGROUND_SERVICE)) { 2883 clientProcState = PROCESS_STATE_FOREGROUND_SERVICE; 2884 } else if (cr.hasFlag(Context.BIND_FOREGROUND_SERVICE)) { 2885 clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 2886 } else if (mService.mWakefulness.get() 2887 == PowerManagerInternal.WAKEFULNESS_AWAKE 2888 && cr.hasFlag(Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)) { 2889 clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 2890 } else { 2891 clientProcState = 2892 PROCESS_STATE_IMPORTANT_FOREGROUND; 2893 } 2894 } else if (clientProcState == PROCESS_STATE_TOP) { 2895 // Go at most to BOUND_TOP, unless requested to elevate 2896 // to client's state. 2897 clientProcState = PROCESS_STATE_BOUND_TOP; 2898 final boolean enabled = cstate.getCachedCompatChange( 2899 CACHED_COMPAT_CHANGE_PROCESS_CAPABILITY); 2900 if (enabled) { 2901 if (cr.hasFlag(Context.BIND_INCLUDE_CAPABILITIES)) { 2902 // TOP process passes all capabilities to the service. 2903 capability |= cstate.getCurCapability(); 2904 } else { 2905 // TOP process passes no capability to the service. 2906 } 2907 } else { 2908 // TOP process passes all capabilities to the service. 2909 capability |= cstate.getCurCapability(); 2910 } 2911 } 2912 } else if (cr.notHasFlag(Context.BIND_IMPORTANT_BACKGROUND)) { 2913 if (clientProcState < PROCESS_STATE_TRANSIENT_BACKGROUND) { 2914 clientProcState = 2915 PROCESS_STATE_TRANSIENT_BACKGROUND; 2916 } 2917 } else { 2918 if (clientProcState < PROCESS_STATE_IMPORTANT_BACKGROUND) { 2919 clientProcState = 2920 PROCESS_STATE_IMPORTANT_BACKGROUND; 2921 } 2922 } 2923 2924 if (cr.hasFlag(Context.BIND_SCHEDULE_LIKE_TOP_APP) && clientIsSystem) { 2925 schedGroup = SCHED_GROUP_TOP_APP; 2926 if (dryRun) { 2927 if (prevSchedGroup < schedGroup) { 2928 // Bail out early, as we only care about the return value for a dryrun. 2929 return true; 2930 } 2931 } else { 2932 state.setScheduleLikeTopApp(true); 2933 } 2934 } 2935 2936 if (!trackedProcState && !dryRun) { 2937 cr.trackProcState(clientProcState, mAdjSeq); 2938 } 2939 2940 if (procState > clientProcState) { 2941 procState = clientProcState; 2942 if (state.setCurRawProcState(procState, dryRun)) { 2943 // Bail out early, as we only care about the return value for a dryrun. 2944 return true; 2945 } 2946 if (adjType == null) { 2947 adjType = "service"; 2948 } 2949 } 2950 if (procState < PROCESS_STATE_IMPORTANT_BACKGROUND 2951 && cr.hasFlag(Context.BIND_SHOWING_UI) && !dryRun) { 2952 app.setPendingUiClean(true); 2953 } 2954 if (adjType != null && !dryRun) { 2955 state.setAdjType(adjType); 2956 state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo 2957 .REASON_SERVICE_IN_USE); 2958 state.setAdjSource(client); 2959 state.setAdjSourceProcState(clientProcState); 2960 state.setAdjTarget(cr.binding.service.instanceName); 2961 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 2962 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType 2963 + ": " + app + ", due to " + client 2964 + " adj=" + adj + " procState=" 2965 + ProcessList.makeProcStateString(procState)); 2966 } 2967 } 2968 } else { // BIND_WAIVE_PRIORITY == true 2969 // BIND_WAIVE_PRIORITY bindings are special when it comes to the 2970 // freezer. Processes bound via WPRI are expected to be running, 2971 // but they are not promoted in the LRU list to keep them out of 2972 // cached. As a result, they can freeze based on oom_adj alone. 2973 // Normally, bindToDeath would fire when a cached app would die 2974 // in the background, but nothing will fire when a running process 2975 // pings a frozen process. Accordingly, any cached app that is 2976 // bound by an unfrozen app via a WPRI binding has to remain 2977 // unfrozen. 2978 if (clientAdj < CACHED_APP_MIN_ADJ) { 2979 if (app.mOptRecord.setShouldNotFreeze(true, dryRun)) { 2980 // Bail out early, as we only care about the return value for a dryrun. 2981 return true; 2982 } 2983 } 2984 } 2985 if (cr.hasFlag(Context.BIND_TREAT_LIKE_ACTIVITY)) { 2986 if (!dryRun) { 2987 app.mServices.setTreatLikeActivity(true); 2988 } 2989 if (clientProcState <= PROCESS_STATE_CACHED_ACTIVITY 2990 && procState > PROCESS_STATE_CACHED_ACTIVITY) { 2991 // This is a cached process, but somebody wants us to treat it like it has 2992 // an activity, okay! 2993 procState = PROCESS_STATE_CACHED_ACTIVITY; 2994 state.setAdjType("cch-as-act"); 2995 } 2996 } 2997 final ActivityServiceConnectionsHolder a = cr.activity; 2998 if (cr.hasFlag(Context.BIND_ADJUST_WITH_ACTIVITY)) { 2999 if (a != null && adj > FOREGROUND_APP_ADJ 3000 && a.isActivityVisible()) { 3001 adj = FOREGROUND_APP_ADJ; 3002 if (state.setCurRawAdj(adj, dryRun)) { 3003 return true; 3004 } 3005 if (cr.notHasFlag(Context.BIND_NOT_FOREGROUND)) { 3006 if (cr.hasFlag(Context.BIND_IMPORTANT)) { 3007 schedGroup = SCHED_GROUP_TOP_APP_BOUND; 3008 } else { 3009 schedGroup = SCHED_GROUP_DEFAULT; 3010 } 3011 } 3012 3013 if (!dryRun) { 3014 state.setAdjType("service"); 3015 state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo 3016 .REASON_SERVICE_IN_USE); 3017 state.setAdjSource(a); 3018 state.setAdjSourceProcState(procState); 3019 state.setAdjTarget(cr.binding.service.instanceName); 3020 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 3021 reportOomAdjMessageLocked(TAG_OOM_ADJ, 3022 "Raise to service w/activity: " + app); 3023 } 3024 } 3025 } 3026 } 3027 3028 capability |= getDefaultCapability(app, procState); 3029 3030 // Procstates below BFGS should never have this capability. 3031 if (procState > PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { 3032 capability &= ~PROCESS_CAPABILITY_BFSL; 3033 } 3034 if (!updated) { 3035 updated = adj < prevRawAdj || procState < prevProcState || schedGroup > prevSchedGroup 3036 || (capability != prevCapability 3037 && (capability & prevCapability) == prevCapability); 3038 } 3039 3040 if (dryRun) { 3041 return updated; 3042 } 3043 if (adj < prevRawAdj) { 3044 schedGroup = setIntermediateAdjLSP(app, adj, prevRawAdj, schedGroup); 3045 } 3046 if (procState < prevProcState) { 3047 setIntermediateProcStateLSP(app, procState, prevProcState); 3048 } 3049 if (schedGroup > prevSchedGroup) { 3050 setIntermediateSchedGroupLSP(state, schedGroup); 3051 } 3052 state.setCurCapability(capability); 3053 3054 return updated; 3055 } 3056 3057 /** 3058 * Computes the impact on {@code app} the provider connections from {@code client} has. 3059 */ 3060 @GuardedBy({"mService", "mProcLock"}) 3061 public boolean computeProviderHostOomAdjLSP(ContentProviderConnection conn, 3062 ProcessRecord app, ProcessRecord client, long now, ProcessRecord topApp, 3063 boolean doingAll, boolean cycleReEval, boolean computeClients, int oomAdjReason, 3064 int cachedAdj, boolean couldRecurse, boolean dryRun) { 3065 if (app.isPendingFinishAttach()) { 3066 // We've set the attaching process state in the computeInitialOomAdjLSP. Skip it here. 3067 return false; 3068 } 3069 3070 final ProcessStateRecord state = app.mState; 3071 final ProcessStateRecord cstate = client.mState; 3072 3073 if (client == app) { 3074 // Being our own client is not interesting. 3075 return false; 3076 } 3077 if (couldRecurse) { 3078 if (computeClients) { 3079 computeOomAdjLSP(client, cachedAdj, topApp, doingAll, now, cycleReEval, true, 3080 oomAdjReason, true); 3081 } else if (couldRecurse) { 3082 cstate.setCurRawAdj(cstate.getCurAdj()); 3083 cstate.setCurRawProcState(cstate.getCurProcState()); 3084 } 3085 3086 if (shouldSkipDueToCycle(app, cstate, state.getCurRawProcState(), state.getCurRawAdj(), 3087 cycleReEval)) { 3088 return false; 3089 } 3090 } 3091 3092 int clientAdj = cstate.getCurRawAdj(); 3093 int clientProcState = cstate.getCurRawProcState(); 3094 3095 int adj = state.getCurRawAdj(); 3096 int procState = state.getCurRawProcState(); 3097 int schedGroup = state.getCurrentSchedulingGroup(); 3098 int capability = state.getCurCapability(); 3099 3100 final int prevRawAdj = adj; 3101 final int prevProcState = procState; 3102 final int prevSchedGroup = schedGroup; 3103 final int prevCapability = capability; 3104 3105 final int appUid = app.info.uid; 3106 final int logUid = mService.mCurOomAdjUid; 3107 3108 // We always propagate PROCESS_CAPABILITY_BFSL to providers here, 3109 // but, right before actually setting it to the process, 3110 // we check the final procstate, and remove it if the procsate is below BFGS. 3111 capability |= getBfslCapabilityFromClient(client); 3112 3113 if (clientProcState >= PROCESS_STATE_CACHED_ACTIVITY) { 3114 // If the other app is cached for any reason, for purposes here 3115 // we are going to consider it empty. 3116 clientProcState = PROCESS_STATE_CACHED_EMPTY; 3117 } 3118 if (client.mOptRecord.shouldNotFreeze()) { 3119 // Propagate the shouldNotFreeze flag down the bindings. 3120 if (app.mOptRecord.setShouldNotFreeze(true, dryRun)) { 3121 // Bail out early, as we only care about the return value for a dryrun. 3122 return true; 3123 } 3124 } 3125 3126 if (!dryRun) { 3127 state.setCurBoundByNonBgRestrictedApp(state.isCurBoundByNonBgRestrictedApp() 3128 || cstate.isCurBoundByNonBgRestrictedApp() 3129 || clientProcState <= PROCESS_STATE_BOUND_TOP 3130 || (clientProcState == PROCESS_STATE_FOREGROUND_SERVICE 3131 && !cstate.isBackgroundRestricted())); 3132 } 3133 3134 String adjType = null; 3135 if (adj > clientAdj) { 3136 if (state.hasShownUi() && !state.getCachedIsHomeProcess() 3137 && clientAdj > PERCEPTIBLE_APP_ADJ) { 3138 adjType = "cch-ui-provider"; 3139 } else { 3140 adj = Math.max(clientAdj, FOREGROUND_APP_ADJ); 3141 if (state.setCurRawAdj(adj, dryRun)) { 3142 // Bail out early, as we only care about the return value for a dryrun. 3143 return true; 3144 } 3145 adjType = "provider"; 3146 } 3147 3148 if (state.isCached() && !cstate.isCached() && dryRun) { 3149 // Bail out early, as we only care about the return value for a dryrun. 3150 return true; 3151 } 3152 } 3153 3154 if (clientProcState <= PROCESS_STATE_FOREGROUND_SERVICE) { 3155 if (adjType == null) { 3156 adjType = "provider"; 3157 } 3158 if (clientProcState == PROCESS_STATE_TOP) { 3159 clientProcState = PROCESS_STATE_BOUND_TOP; 3160 } else { 3161 clientProcState = PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 3162 } 3163 } 3164 3165 if (!dryRun) { 3166 conn.trackProcState(clientProcState, mAdjSeq); 3167 } 3168 if (procState > clientProcState) { 3169 procState = clientProcState; 3170 if (state.setCurRawProcState(procState, dryRun)) { 3171 // Bail out early, as we only care about the return value for a dryrun. 3172 return true; 3173 } 3174 } 3175 if (cstate.getCurrentSchedulingGroup() > schedGroup) { 3176 schedGroup = SCHED_GROUP_DEFAULT; 3177 } 3178 if (adjType != null && !dryRun) { 3179 state.setAdjType(adjType); 3180 state.setAdjTypeCode(ActivityManager.RunningAppProcessInfo 3181 .REASON_PROVIDER_IN_USE); 3182 state.setAdjSource(client); 3183 state.setAdjSourceProcState(clientProcState); 3184 state.setAdjTarget(conn.provider.name); 3185 if (DEBUG_OOM_ADJ_REASON || logUid == appUid) { 3186 reportOomAdjMessageLocked(TAG_OOM_ADJ, "Raise to " + adjType 3187 + ": " + app + ", due to " + client 3188 + " adj=" + adj + " procState=" 3189 + ProcessList.makeProcStateString(procState)); 3190 } 3191 } 3192 3193 // Procstates below BFGS should never have this capability. 3194 if (procState > PROCESS_STATE_BOUND_FOREGROUND_SERVICE) { 3195 capability &= ~PROCESS_CAPABILITY_BFSL; 3196 } 3197 3198 if (dryRun && (adj < prevRawAdj || procState < prevProcState || schedGroup > prevSchedGroup 3199 || (capability != prevCapability 3200 && (capability & prevCapability) == prevCapability))) { 3201 return true; 3202 } 3203 3204 if (adj < prevRawAdj) { 3205 schedGroup = setIntermediateAdjLSP(app, adj, prevRawAdj, schedGroup); 3206 } 3207 if (procState < prevProcState) { 3208 setIntermediateProcStateLSP(app, procState, prevProcState); 3209 } 3210 if (schedGroup > prevSchedGroup) { 3211 setIntermediateSchedGroupLSP(state, schedGroup); 3212 } 3213 state.setCurCapability(capability); 3214 3215 return false; 3216 } 3217 getDefaultCapability(ProcessRecord app, int procState)3218 protected int getDefaultCapability(ProcessRecord app, int procState) { 3219 final int networkCapabilities = 3220 NetworkPolicyManager.getDefaultProcessNetworkCapabilities(procState); 3221 final int baseCapabilities; 3222 switch (procState) { 3223 case PROCESS_STATE_PERSISTENT: 3224 case PROCESS_STATE_PERSISTENT_UI: 3225 case PROCESS_STATE_TOP: 3226 baseCapabilities = PROCESS_CAPABILITY_ALL; // BFSL allowed 3227 break; 3228 case PROCESS_STATE_BOUND_TOP: 3229 baseCapabilities = PROCESS_CAPABILITY_BFSL; 3230 break; 3231 case PROCESS_STATE_FOREGROUND_SERVICE: 3232 if (app.getActiveInstrumentation() != null) { 3233 baseCapabilities = PROCESS_CAPABILITY_ALL_IMPLICIT; 3234 } else { 3235 // Capability from foreground service is conditional depending on 3236 // foregroundServiceType in the manifest file and the 3237 // mAllowWhileInUsePermissionInFgs flag. 3238 baseCapabilities = PROCESS_CAPABILITY_NONE; 3239 } 3240 break; 3241 default: 3242 baseCapabilities = PROCESS_CAPABILITY_NONE; 3243 break; 3244 } 3245 return baseCapabilities | networkCapabilities; 3246 } 3247 3248 /** 3249 * @return the BFSL capability from a client (of a service binding or provider). 3250 */ getBfslCapabilityFromClient(ProcessRecord client)3251 protected int getBfslCapabilityFromClient(ProcessRecord client) { 3252 // Procstates above FGS should always have this flag. We shouldn't need this logic, 3253 // but let's do it just in case. 3254 if (client.mState.getCurProcState() < PROCESS_STATE_FOREGROUND_SERVICE) { 3255 return PROCESS_CAPABILITY_BFSL; 3256 } 3257 // Otherwise, use the process's cur capability. 3258 3259 // Note: BFSL is a per-UID check, not per-process, but here, the BFSL capability is still 3260 // propagated on a per-process basis. 3261 // 3262 // For example, consider this case: 3263 // - There are App 1 and App 2. 3264 // - App 1 has two processes 3265 // Proc #1A, procstate BFGS with CAPABILITY_BFSL 3266 // Proc #1B, procstate FGS with no CAPABILITY_BFSL (i.e. process has a short FGS) 3267 // And this process binds to Proc #2 of App 2. 3268 // 3269 // (Note because #1A has CAPABILITY_BFSL, App 1's UidRecord has CAPABILITY_BFSL.) 3270 // 3271 // - App 2 has one process: 3272 // Proc #2, procstate FGS due to the above binding, _with no CAPABILITY_BFSL_. 3273 // 3274 // In this case, #2 will not get CAPABILITY_BFSL because the binding client (#1B) 3275 // doesn't have this capability. (Even though App 1's UidRecord has it.) 3276 // 3277 // This may look weird, because App 2 _is_ still BFSL allowed, because "it's bound by 3278 // an app that is BFSL-allowed". (See [bookmark: 61867f60-007c-408c-a2c4-e19e96056135] 3279 // in ActiveServices.) 3280 // 3281 // So why don't we propagate PROCESS_CAPABILITY_BFSL from App 1's UID record? 3282 // This is because short-FGS acts like "below BFGS" as far as BFSL is concerned, 3283 // similar to how JobScheduler jobs are below BFGS and apps can't start FGS from there. 3284 // 3285 // If #1B was running a job instead of a short-FGS, then its procstate would be below BFGS. 3286 // Then #2's procstate would also be below BFGS. So #2 wouldn't get CAPABILITY_BFSL. 3287 // Similarly, if #1B has a short FGS, even though the procstate of #1B and #2 would be FGS, 3288 // they both still wouldn't get CAPABILITY_BFSL. 3289 // 3290 // However, again, because #2 is bound by App 1, which is BFSL-allowed (because of #1A) 3291 // App 2 would still BFSL-allowed, due to the aforementioned check in ActiveServices. 3292 return client.mState.getCurCapability() & PROCESS_CAPABILITY_BFSL; 3293 } 3294 3295 /** 3296 * Checks if for the given app and client, there's a cycle that should skip over the client 3297 * for now or use partial values to evaluate the effect of the client binding. 3298 * @param app 3299 * @param client 3300 * @param procState procstate evaluated so far for this app 3301 * @param adj oom_adj evaluated so far for this app 3302 * @param cycleReEval whether we're currently re-evaluating due to a cycle, and not the first 3303 * evaluation. 3304 * @return whether to skip using the client connection at this time 3305 */ shouldSkipDueToCycle(ProcessRecord app, ProcessStateRecord client, int procState, int adj, boolean cycleReEval)3306 private boolean shouldSkipDueToCycle(ProcessRecord app, ProcessStateRecord client, 3307 int procState, int adj, boolean cycleReEval) { 3308 if (client.containsCycle()) { 3309 // We've detected a cycle. We should retry computeOomAdjLSP later in 3310 // case a later-checked connection from a client would raise its 3311 // priority legitimately. 3312 app.mState.setContainsCycle(true); 3313 mProcessesInCycle.add(app); 3314 // If the client has not been completely evaluated, check if it's worth 3315 // using the partial values. 3316 if (client.getCompletedAdjSeq() < mAdjSeq) { 3317 if (cycleReEval) { 3318 // If the partial values are no better, skip until the next 3319 // attempt 3320 if (client.getCurRawProcState() >= procState 3321 && client.getCurRawAdj() >= adj 3322 && (client.getCurCapability() & app.mState.getCurCapability()) 3323 == client.getCurCapability()) { 3324 return true; 3325 } 3326 // Else use the client's partial procstate and adj to adjust the 3327 // effect of the binding 3328 } else { 3329 return false; 3330 } 3331 } 3332 } 3333 return false; 3334 } 3335 3336 /** Inform the oomadj observer of changes to oomadj. Used by tests. */ 3337 @GuardedBy("mService") reportOomAdjMessageLocked(String tag, String msg)3338 protected void reportOomAdjMessageLocked(String tag, String msg) { 3339 Slog.d(tag, msg); 3340 synchronized (mService.mOomAdjObserverLock) { 3341 if (mService.mCurOomAdjObserver != null) { 3342 mService.mUiHandler.obtainMessage(DISPATCH_OOM_ADJ_OBSERVER_MSG, msg) 3343 .sendToTarget(); 3344 } 3345 } 3346 } 3347 onWakefulnessChanged(int wakefulness)3348 void onWakefulnessChanged(int wakefulness) { 3349 mCachedAppOptimizer.onWakefulnessChanged(wakefulness); 3350 } 3351 3352 @GuardedBy({"mService", "mProcLock"}) applyOomAdjLSP(ProcessRecord app, boolean doingAll, long now, long nowElapsed, @OomAdjReason int oomAdjReason)3353 protected boolean applyOomAdjLSP(ProcessRecord app, boolean doingAll, long now, 3354 long nowElapsed, @OomAdjReason int oomAdjReason) { 3355 return applyOomAdjLSP(app, doingAll, now, nowElapsed, oomAdjReason, false); 3356 } 3357 3358 /** Applies the computed oomadj, procstate and sched group values and freezes them in set* */ 3359 @GuardedBy({"mService", "mProcLock"}) applyOomAdjLSP(ProcessRecord app, boolean doingAll, long now, long nowElapsed, @OomAdjReason int oomAdjReson, boolean isBatchingOomAdj)3360 protected boolean applyOomAdjLSP(ProcessRecord app, boolean doingAll, long now, 3361 long nowElapsed, @OomAdjReason int oomAdjReson, boolean isBatchingOomAdj) { 3362 boolean success = true; 3363 final ProcessStateRecord state = app.mState; 3364 final UidRecord uidRec = app.getUidRecord(); 3365 3366 if (state.getCurRawAdj() != state.getSetRawAdj()) { 3367 state.setSetRawAdj(state.getCurRawAdj()); 3368 } 3369 3370 int changes = 0; 3371 3372 if (state.getCurAdj() != state.getSetAdj()) { 3373 mCachedAppOptimizer.onOomAdjustChanged(state.getSetAdj(), state.getCurAdj(), app); 3374 } 3375 3376 final int oldOomAdj = state.getSetAdj(); 3377 if (state.getCurAdj() != state.getSetAdj()) { 3378 if (isBatchingOomAdj && mConstants.ENABLE_BATCHING_OOM_ADJ) { 3379 mProcsToOomAdj.add(app); 3380 } else { 3381 ProcessList.setOomAdj(app.getPid(), app.uid, state.getCurAdj()); 3382 } 3383 3384 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.info.uid) { 3385 String msg = "Set " + app.getPid() + " " + app.processName + " adj " 3386 + state.getCurAdj() + ": " + state.getAdjType(); 3387 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); 3388 } 3389 state.setSetAdj(state.getCurAdj()); 3390 if (uidRec != null) { 3391 uidRec.noteProcAdjChanged(); 3392 } 3393 state.setVerifiedAdj(INVALID_ADJ); 3394 } 3395 3396 final int curSchedGroup = state.getCurrentSchedulingGroup(); 3397 if (app.getWaitingToKill() != null && app.mReceivers.numberOfCurReceivers() == 0 3398 && ActivityManager.isProcStateBackground(state.getCurProcState()) 3399 && !state.hasStartedServices()) { 3400 app.killLocked(app.getWaitingToKill(), ApplicationExitInfo.REASON_USER_REQUESTED, 3401 ApplicationExitInfo.SUBREASON_REMOVE_TASK, true); 3402 success = false; 3403 } else if (state.getSetSchedGroup() != curSchedGroup) { 3404 int oldSchedGroup = state.getSetSchedGroup(); 3405 state.setSetSchedGroup(curSchedGroup); 3406 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.uid) { 3407 String msg = "Setting sched group of " + app.processName 3408 + " to " + curSchedGroup + ": " + state.getAdjType(); 3409 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); 3410 } 3411 int processGroup; 3412 switch (curSchedGroup) { 3413 case SCHED_GROUP_BACKGROUND: 3414 processGroup = THREAD_GROUP_BACKGROUND; 3415 break; 3416 case SCHED_GROUP_TOP_APP: 3417 case SCHED_GROUP_TOP_APP_BOUND: 3418 processGroup = THREAD_GROUP_TOP_APP; 3419 break; 3420 case SCHED_GROUP_RESTRICTED: 3421 processGroup = THREAD_GROUP_RESTRICTED; 3422 break; 3423 default: 3424 processGroup = THREAD_GROUP_DEFAULT; 3425 break; 3426 } 3427 mProcessGroupHandler.sendMessage(mProcessGroupHandler.obtainMessage( 3428 0 /* unused */, app.getPid(), processGroup, app.processName)); 3429 try { 3430 final int renderThreadTid = app.getRenderThreadTid(); 3431 if (curSchedGroup == SCHED_GROUP_TOP_APP) { 3432 // do nothing if we already switched to RT 3433 if (oldSchedGroup != SCHED_GROUP_TOP_APP) { 3434 app.getWindowProcessController().onTopProcChanged(); 3435 if (app.useFifoUiScheduling()) { 3436 // Switch UI pipeline for app to SCHED_FIFO 3437 state.setSavedPriority(Process.getThreadPriority(app.getPid())); 3438 ActivityManagerService.setFifoPriority(app, true /* enable */); 3439 } else { 3440 // Boost priority for top app UI and render threads 3441 setThreadPriority(app.getPid(), THREAD_PRIORITY_TOP_APP_BOOST); 3442 if (renderThreadTid != 0) { 3443 try { 3444 setThreadPriority(renderThreadTid, 3445 THREAD_PRIORITY_TOP_APP_BOOST); 3446 } catch (IllegalArgumentException e) { 3447 // thread died, ignore 3448 } 3449 } 3450 } 3451 } 3452 } else if (oldSchedGroup == SCHED_GROUP_TOP_APP 3453 && curSchedGroup != SCHED_GROUP_TOP_APP) { 3454 app.getWindowProcessController().onTopProcChanged(); 3455 if (app.useFifoUiScheduling()) { 3456 // Reset UI pipeline to SCHED_OTHER 3457 ActivityManagerService.setFifoPriority(app, false /* enable */); 3458 setThreadPriority(app.getPid(), state.getSavedPriority()); 3459 } else { 3460 // Reset priority for top app UI and render threads 3461 setThreadPriority(app.getPid(), 0); 3462 } 3463 3464 if (renderThreadTid != 0) { 3465 setThreadPriority(renderThreadTid, THREAD_PRIORITY_DISPLAY); 3466 } 3467 } 3468 } catch (Exception e) { 3469 if (DEBUG_ALL) { 3470 Slog.w(TAG, "Failed setting thread priority of " + app.getPid(), e); 3471 } 3472 } 3473 } 3474 if (state.hasRepForegroundActivities() != state.hasForegroundActivities()) { 3475 state.setRepForegroundActivities(state.hasForegroundActivities()); 3476 changes |= ActivityManagerService.ProcessChangeItem.CHANGE_ACTIVITIES; 3477 } 3478 3479 updateAppFreezeStateLSP(app, oomAdjReson, false); 3480 3481 if (state.getReportedProcState() != state.getCurProcState()) { 3482 state.setReportedProcState(state.getCurProcState()); 3483 if (app.getThread() != null) { 3484 try { 3485 if (false) { 3486 //RuntimeException h = new RuntimeException("here"); 3487 Slog.i(TAG, "Sending new process state " + state.getReportedProcState() 3488 + " to " + app /*, h*/); 3489 } 3490 app.getThread().setProcessState(state.getReportedProcState()); 3491 } catch (RemoteException e) { 3492 } 3493 } 3494 } 3495 boolean forceUpdatePssTime = false; 3496 if (state.getSetProcState() == PROCESS_STATE_NONEXISTENT 3497 || ProcessList.procStatesDifferForMem( 3498 state.getCurProcState(), state.getSetProcState())) { 3499 state.setLastStateTime(now); 3500 forceUpdatePssTime = true; 3501 if (DEBUG_PSS) { 3502 Slog.d(TAG_PSS, "Process state change from " 3503 + ProcessList.makeProcStateString(state.getSetProcState()) + " to " 3504 + ProcessList.makeProcStateString(state.getCurProcState()) + " next pss in " 3505 + (app.mProfile.getNextPssTime() - now) + ": " + app); 3506 } 3507 } 3508 synchronized (mService.mAppProfiler.mProfilerLock) { 3509 app.mProfile.updateProcState(app.mState); 3510 mService.mAppProfiler.updateNextPssTimeLPf( 3511 state.getCurProcState(), app.mProfile, now, forceUpdatePssTime); 3512 } 3513 int oldProcState = state.getSetProcState(); 3514 if (state.getSetProcState() != state.getCurProcState()) { 3515 if (DEBUG_SWITCH || DEBUG_OOM_ADJ || mService.mCurOomAdjUid == app.uid) { 3516 String msg = "Proc state change of " + app.processName 3517 + " to " + ProcessList.makeProcStateString(state.getCurProcState()) 3518 + " (" + state.getCurProcState() + ")" + ": " + state.getAdjType(); 3519 reportOomAdjMessageLocked(TAG_OOM_ADJ, msg); 3520 } 3521 boolean setImportant = state.getSetProcState() < PROCESS_STATE_SERVICE; 3522 boolean curImportant = state.getCurProcState() < PROCESS_STATE_SERVICE; 3523 if (setImportant && !curImportant) { 3524 // This app is no longer something we consider important enough to allow to use 3525 // arbitrary amounts of battery power. Note its current CPU time to later know to 3526 // kill it if it is not behaving well. 3527 state.setWhenUnimportant(now); 3528 app.mProfile.mLastCpuTime.set(0); 3529 } 3530 // Inform UsageStats of important process state change 3531 // Must be called before updating setProcState 3532 maybeUpdateUsageStatsLSP(app, nowElapsed); 3533 3534 maybeUpdateLastTopTime(state, now); 3535 3536 state.setSetProcState(state.getCurProcState()); 3537 if (state.getSetProcState() >= ActivityManager.PROCESS_STATE_HOME) { 3538 state.setNotCachedSinceIdle(false); 3539 } 3540 if (!doingAll) { 3541 synchronized (mService.mProcessStats.mLock) { 3542 mService.setProcessTrackerStateLOSP(app, 3543 mService.mProcessStats.getMemFactorLocked()); 3544 } 3545 } else { 3546 state.setProcStateChanged(true); 3547 } 3548 } else if (state.hasReportedInteraction()) { 3549 final boolean fgsInteractionChangeEnabled = state.getCachedCompatChange( 3550 CACHED_COMPAT_CHANGE_USE_SHORT_FGS_USAGE_INTERACTION_TIME); 3551 final long interactionThreshold = fgsInteractionChangeEnabled 3552 ? mConstants.USAGE_STATS_INTERACTION_INTERVAL_POST_S 3553 : mConstants.USAGE_STATS_INTERACTION_INTERVAL_PRE_S; 3554 // For apps that sit around for a long time in the interactive state, we need 3555 // to report this at least once a day so they don't go idle. 3556 if ((nowElapsed - state.getInteractionEventTime()) > interactionThreshold) { 3557 maybeUpdateUsageStatsLSP(app, nowElapsed); 3558 } 3559 } else { 3560 final boolean fgsInteractionChangeEnabled = state.getCachedCompatChange( 3561 CACHED_COMPAT_CHANGE_USE_SHORT_FGS_USAGE_INTERACTION_TIME); 3562 final long interactionThreshold = fgsInteractionChangeEnabled 3563 ? mConstants.SERVICE_USAGE_INTERACTION_TIME_POST_S 3564 : mConstants.SERVICE_USAGE_INTERACTION_TIME_PRE_S; 3565 // For foreground services that sit around for a long time but are not interacted with. 3566 if ((nowElapsed - state.getFgInteractionTime()) > interactionThreshold) { 3567 maybeUpdateUsageStatsLSP(app, nowElapsed); 3568 } 3569 } 3570 3571 if (state.getCurCapability() != state.getSetCapability()) { 3572 state.setSetCapability(state.getCurCapability()); 3573 } 3574 3575 final boolean curBoundByNonBgRestrictedApp = state.isCurBoundByNonBgRestrictedApp(); 3576 if (curBoundByNonBgRestrictedApp != state.isSetBoundByNonBgRestrictedApp()) { 3577 state.setSetBoundByNonBgRestrictedApp(curBoundByNonBgRestrictedApp); 3578 if (!curBoundByNonBgRestrictedApp && state.isBackgroundRestricted()) { 3579 mService.mHandler.post(() -> { 3580 synchronized (mService) { 3581 mService.mServices.stopAllForegroundServicesLocked( 3582 app.uid, app.info.packageName); 3583 } 3584 }); 3585 } 3586 } 3587 3588 if (changes != 0) { 3589 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 3590 "Changes in " + app + ": " + changes); 3591 ActivityManagerService.ProcessChangeItem item = 3592 mProcessList.enqueueProcessChangeItemLocked(app.getPid(), app.info.uid); 3593 item.changes |= changes; 3594 item.foregroundActivities = state.hasRepForegroundActivities(); 3595 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS, 3596 "Item " + Integer.toHexString(System.identityHashCode(item)) 3597 + " " + app.toShortString() + ": changes=" + item.changes 3598 + " foreground=" + item.foregroundActivities 3599 + " type=" + state.getAdjType() + " source=" + state.getAdjSource() 3600 + " target=" + state.getAdjTarget()); 3601 } 3602 3603 if (state.isCached() && !state.shouldNotKillOnBgRestrictedAndIdle()) { 3604 // It's eligible to get killed when in UID idle and bg restricted mode, 3605 // check if these states are just flipped. 3606 if (!state.isSetCached() || state.isSetNoKillOnBgRestrictedAndIdle()) { 3607 // Take the timestamp, we'd hold the killing for the background settle time 3608 // (for states debouncing to avoid from thrashing). 3609 state.setLastCanKillOnBgRestrictedAndIdleTime(nowElapsed); 3610 // Kick off the delayed checkup message if needed. 3611 if (mService.mDeterministicUidIdle 3612 || !mService.mHandler.hasMessages(IDLE_UIDS_MSG)) { 3613 if (mLogger.shouldLog(app.uid)) { 3614 mLogger.logScheduleUidIdle2( 3615 uidRec.getUid(), app.getPid(), 3616 mConstants.mKillBgRestrictedAndCachedIdleSettleTimeMs); 3617 } 3618 mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, 3619 mConstants.mKillBgRestrictedAndCachedIdleSettleTimeMs); 3620 } 3621 } 3622 } 3623 state.setSetCached(state.isCached()); 3624 state.setSetNoKillOnBgRestrictedAndIdle(state.shouldNotKillOnBgRestrictedAndIdle()); 3625 if (((oldProcState != state.getSetProcState()) || (oldOomAdj != state.getSetAdj())) 3626 && mLogger.shouldLog(app.uid)) { 3627 mLogger.logProcStateChanged(app.uid, app.getPid(), 3628 state.getSetProcState(), oldProcState, 3629 state.getSetAdj(), oldOomAdj); 3630 } 3631 3632 return success; 3633 } 3634 3635 @GuardedBy({"mService", "mProcLock"}) setAttachingProcessStatesLSP(ProcessRecord app)3636 void setAttachingProcessStatesLSP(ProcessRecord app) { 3637 int initialSchedGroup = SCHED_GROUP_DEFAULT; 3638 int initialProcState = PROCESS_STATE_CACHED_EMPTY; 3639 int initialCapability = PROCESS_CAPABILITY_NONE; 3640 boolean initialCached = true; 3641 final ProcessStateRecord state = app.mState; 3642 final int prevProcState = state.getCurProcState(); 3643 final int prevAdj = state.getCurRawAdj(); 3644 // If the process has been marked as foreground, it is starting as the top app (with 3645 // Zygote#START_AS_TOP_APP_ARG), so boost the thread priority of its default UI thread. 3646 if (state.hasForegroundActivities()) { 3647 try { 3648 // The priority must be the same as how does {@link #applyOomAdjLSP} set for 3649 // {@link SCHED_GROUP_TOP_APP}. We don't check render thread because it 3650 // is not ready when attaching. 3651 app.getWindowProcessController().onTopProcChanged(); 3652 if (app.useFifoUiScheduling()) { 3653 mService.scheduleAsFifoPriority(app.getPid(), true); 3654 } else { 3655 setThreadPriority(app.getPid(), THREAD_PRIORITY_TOP_APP_BOOST); 3656 } 3657 if (isScreenOnOrAnimatingLocked(state)) { 3658 initialSchedGroup = SCHED_GROUP_TOP_APP; 3659 initialProcState = PROCESS_STATE_TOP; 3660 } 3661 initialCapability = PROCESS_CAPABILITY_ALL; 3662 initialCached = false; 3663 } catch (Exception e) { 3664 Slog.w(TAG, "Failed to pre-set top priority to " + app + " " + e); 3665 } 3666 } 3667 3668 state.setCurrentSchedulingGroup(initialSchedGroup); 3669 state.setCurProcState(initialProcState); 3670 state.setCurRawProcState(initialProcState); 3671 state.setCurCapability(initialCapability); 3672 3673 state.setCurAdj(ProcessList.FOREGROUND_APP_ADJ); 3674 state.setCurRawAdj(ProcessList.FOREGROUND_APP_ADJ); 3675 state.setForcingToImportant(null); 3676 state.setHasShownUi(false); 3677 3678 onProcessStateChanged(app, prevProcState); 3679 onProcessOomAdjChanged(app, prevAdj); 3680 } 3681 3682 // ONLY used for unit testing in OomAdjusterTests.java 3683 @VisibleForTesting maybeUpdateUsageStats(ProcessRecord app, long nowElapsed)3684 void maybeUpdateUsageStats(ProcessRecord app, long nowElapsed) { 3685 synchronized (mService) { 3686 synchronized (mProcLock) { 3687 maybeUpdateUsageStatsLSP(app, nowElapsed); 3688 } 3689 } 3690 } 3691 3692 @GuardedBy({"mService", "mProcLock"}) maybeUpdateUsageStatsLSP(ProcessRecord app, long nowElapsed)3693 private void maybeUpdateUsageStatsLSP(ProcessRecord app, long nowElapsed) { 3694 final ProcessStateRecord state = app.mState; 3695 if (DEBUG_USAGE_STATS) { 3696 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList()) 3697 + "] state changes: old = " + state.getSetProcState() + ", new = " 3698 + state.getCurProcState()); 3699 } 3700 if (mService.mUsageStatsService == null) { 3701 return; 3702 } 3703 final boolean fgsInteractionChangeEnabled = state.getCachedCompatChange( 3704 CACHED_COMPAT_CHANGE_USE_SHORT_FGS_USAGE_INTERACTION_TIME); 3705 boolean isInteraction; 3706 // To avoid some abuse patterns, we are going to be careful about what we consider 3707 // to be an app interaction. Being the top activity doesn't count while the display 3708 // is sleeping, nor do short foreground services. 3709 if (ActivityManager.isProcStateConsideredInteraction(state.getCurProcState())) { 3710 isInteraction = true; 3711 state.setFgInteractionTime(0); 3712 } else if (state.getCurProcState() <= PROCESS_STATE_FOREGROUND_SERVICE) { 3713 if (state.getFgInteractionTime() == 0) { 3714 state.setFgInteractionTime(nowElapsed); 3715 isInteraction = false; 3716 } else { 3717 final long interactionTime = fgsInteractionChangeEnabled 3718 ? mConstants.SERVICE_USAGE_INTERACTION_TIME_POST_S 3719 : mConstants.SERVICE_USAGE_INTERACTION_TIME_PRE_S; 3720 isInteraction = nowElapsed > state.getFgInteractionTime() + interactionTime; 3721 } 3722 } else { 3723 isInteraction = 3724 state.getCurProcState() <= PROCESS_STATE_IMPORTANT_FOREGROUND; 3725 state.setFgInteractionTime(0); 3726 } 3727 final long interactionThreshold = fgsInteractionChangeEnabled 3728 ? mConstants.USAGE_STATS_INTERACTION_INTERVAL_POST_S 3729 : mConstants.USAGE_STATS_INTERACTION_INTERVAL_PRE_S; 3730 if (isInteraction 3731 && (!state.hasReportedInteraction() 3732 || (nowElapsed - state.getInteractionEventTime()) > interactionThreshold)) { 3733 state.setInteractionEventTime(nowElapsed); 3734 String[] packages = app.getPackageList(); 3735 if (packages != null) { 3736 for (int i = 0; i < packages.length; i++) { 3737 mService.mUsageStatsService.reportEvent(packages[i], app.userId, 3738 UsageEvents.Event.SYSTEM_INTERACTION); 3739 } 3740 } 3741 } 3742 state.setReportedInteraction(isInteraction); 3743 if (!isInteraction) { 3744 state.setInteractionEventTime(0); 3745 } 3746 } 3747 maybeUpdateLastTopTime(ProcessStateRecord state, long nowUptime)3748 private void maybeUpdateLastTopTime(ProcessStateRecord state, long nowUptime) { 3749 if (state.getSetProcState() <= PROCESS_STATE_TOP 3750 && state.getCurProcState() > PROCESS_STATE_TOP) { 3751 state.setLastTopTime(nowUptime); 3752 } 3753 } 3754 3755 /** 3756 * Look for recently inactive apps and mark them idle after a grace period. If idled, stop 3757 * any background services and inform listeners. 3758 */ 3759 @GuardedBy("mService") idleUidsLocked()3760 void idleUidsLocked() { 3761 final int N = mActiveUids.size(); 3762 mService.mHandler.removeMessages(IDLE_UIDS_MSG); 3763 if (N <= 0) { 3764 return; 3765 } 3766 final long nowElapsed = mInjector.getElapsedRealtimeMillis(); 3767 final long maxBgTime = nowElapsed - mConstants.BACKGROUND_SETTLE_TIME; 3768 long nextTime = 0; 3769 if (mService.mLocalPowerManager != null) { 3770 mService.mLocalPowerManager.startUidChanges(); 3771 } 3772 boolean shouldLogMisc = false; 3773 for (int i = N - 1; i >= 0; i--) { 3774 final UidRecord uidRec = mActiveUids.valueAt(i); 3775 final long bgTime = uidRec.getLastBackgroundTime(); 3776 final long idleTime = uidRec.getLastIdleTimeIfStillIdle(); 3777 if (bgTime > 0 && (!uidRec.isIdle() || idleTime == 0)) { 3778 if (bgTime <= maxBgTime) { 3779 EventLogTags.writeAmUidIdle(uidRec.getUid()); 3780 synchronized (mProcLock) { 3781 uidRec.setIdle(true); 3782 uidRec.setSetIdle(true); 3783 uidRec.setLastIdleTime(nowElapsed); 3784 } 3785 mService.doStopUidLocked(uidRec.getUid(), uidRec); 3786 } else { 3787 if (nextTime == 0 || nextTime > bgTime) { 3788 nextTime = bgTime; 3789 } 3790 if (mLogger.shouldLog(uidRec.getUid())) { 3791 shouldLogMisc = true; 3792 } 3793 } 3794 } 3795 } 3796 if (mService.mLocalPowerManager != null) { 3797 mService.mLocalPowerManager.finishUidChanges(); 3798 } 3799 // Also check if there are any apps in cached and background restricted mode, 3800 // if so, kill it if it's been there long enough, or kick off a msg to check 3801 // it later. 3802 if (mService.mConstants.mKillBgRestrictedAndCachedIdle) { 3803 final ArraySet<ProcessRecord> apps = mProcessList.mAppsInBackgroundRestricted; 3804 for (int i = 0, size = apps.size(); i < size; i++) { 3805 // Check to see if needs to be killed. 3806 final long bgTime = mProcessList.killAppIfBgRestrictedAndCachedIdleLocked( 3807 apps.valueAt(i), nowElapsed) - mConstants.BACKGROUND_SETTLE_TIME; 3808 if (bgTime > 0 && (nextTime == 0 || nextTime > bgTime)) { 3809 nextTime = bgTime; 3810 } 3811 } 3812 } 3813 if (nextTime > 0) { 3814 long delay = nextTime + mConstants.BACKGROUND_SETTLE_TIME - nowElapsed; 3815 if (shouldLogMisc) { 3816 mLogger.logScheduleUidIdle3(delay); 3817 } 3818 mService.mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, delay); 3819 } 3820 } 3821 3822 @GuardedBy({"mService", "mProcLock"}) setUidTempAllowlistStateLSP(int uid, boolean onAllowlist)3823 void setUidTempAllowlistStateLSP(int uid, boolean onAllowlist) { 3824 final UidRecord uidRec = mActiveUids.get(uid); 3825 if (uidRec != null && uidRec.isCurAllowListed() != onAllowlist) { 3826 uidRec.setCurAllowListed(onAllowlist); 3827 if (Flags.migrateFullOomadjUpdates()) { 3828 for (int i = uidRec.getNumOfProcs() - 1; i >= 0; i--) { 3829 enqueueOomAdjTargetLocked(uidRec.getProcessRecordByIndex(i)); 3830 } 3831 updateOomAdjPendingTargetsLocked(OOM_ADJ_REASON_ALLOWLIST); 3832 } else { 3833 updateOomAdjLSP(OOM_ADJ_REASON_ALLOWLIST); 3834 } 3835 } 3836 } 3837 3838 @GuardedBy("mService") dumpProcessListVariablesLocked(ProtoOutputStream proto)3839 void dumpProcessListVariablesLocked(ProtoOutputStream proto) { 3840 proto.write(ActivityManagerServiceDumpProcessesProto.ADJ_SEQ, mAdjSeq); 3841 proto.write(ActivityManagerServiceDumpProcessesProto.LRU_SEQ, mProcessList.getLruSeqLOSP()); 3842 proto.write(ActivityManagerServiceDumpProcessesProto.NUM_NON_CACHED_PROCS, 3843 mNumNonCachedProcs); 3844 proto.write(ActivityManagerServiceDumpProcessesProto.NUM_SERVICE_PROCS, mNumServiceProcs); 3845 proto.write(ActivityManagerServiceDumpProcessesProto.NEW_NUM_SERVICE_PROCS, 3846 mNewNumServiceProcs); 3847 3848 } 3849 3850 @GuardedBy("mService") dumpSequenceNumbersLocked(PrintWriter pw)3851 void dumpSequenceNumbersLocked(PrintWriter pw) { 3852 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mProcessList.getLruSeqLOSP()); 3853 } 3854 3855 @GuardedBy("mService") dumpProcCountsLocked(PrintWriter pw)3856 void dumpProcCountsLocked(PrintWriter pw) { 3857 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs 3858 + " (" + mProcessList.getLruSizeLOSP() + " total)" 3859 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs 3860 + " mNumServiceProcs=" + mNumServiceProcs 3861 + " mNewNumServiceProcs=" + mNewNumServiceProcs); 3862 } 3863 3864 @GuardedBy("mProcLock") dumpCachedAppOptimizerSettings(PrintWriter pw)3865 void dumpCachedAppOptimizerSettings(PrintWriter pw) { 3866 mCachedAppOptimizer.dump(pw); 3867 } 3868 3869 @GuardedBy("mService") dumpCacheOomRankerSettings(PrintWriter pw)3870 void dumpCacheOomRankerSettings(PrintWriter pw) { 3871 mCacheOomRanker.dump(pw); 3872 } 3873 3874 @GuardedBy({"mService", "mProcLock"}) updateAppFreezeStateLSP(ProcessRecord app, @OomAdjReason int oomAdjReason, boolean immediate)3875 void updateAppFreezeStateLSP(ProcessRecord app, @OomAdjReason int oomAdjReason, 3876 boolean immediate) { 3877 if (!mCachedAppOptimizer.useFreezer()) { 3878 return; 3879 } 3880 3881 if (app.mOptRecord.isFreezeExempt()) { 3882 return; 3883 } 3884 3885 final ProcessCachedOptimizerRecord opt = app.mOptRecord; 3886 // if an app is already frozen and shouldNotFreeze becomes true, immediately unfreeze 3887 if (opt.isFrozen() && opt.shouldNotFreeze()) { 3888 mCachedAppOptimizer.unfreezeAppLSP(app, 3889 CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(oomAdjReason)); 3890 return; 3891 } 3892 3893 final ProcessStateRecord state = app.mState; 3894 // Use current adjustment when freezing, set adjustment when unfreezing. 3895 if (state.getCurAdj() >= FREEZER_CUTOFF_ADJ && !opt.isFrozen() 3896 && !opt.shouldNotFreeze()) { 3897 if (!immediate) { 3898 mCachedAppOptimizer.freezeAppAsyncLSP(app); 3899 } else { 3900 mCachedAppOptimizer.freezeAppAsyncAtEarliestLSP(app); 3901 } 3902 } else if (state.getSetAdj() < FREEZER_CUTOFF_ADJ) { 3903 mCachedAppOptimizer.unfreezeAppLSP(app, 3904 CachedAppOptimizer.getUnfreezeReasonCodeFromOomAdjReason(oomAdjReason)); 3905 } 3906 } 3907 3908 @GuardedBy("mService") unfreezeTemporarily(ProcessRecord app, @OomAdjReason int reason)3909 void unfreezeTemporarily(ProcessRecord app, @OomAdjReason int reason) { 3910 if (!mCachedAppOptimizer.useFreezer()) { 3911 return; 3912 } 3913 3914 final ProcessCachedOptimizerRecord opt = app.mOptRecord; 3915 if (!opt.isFrozen() && !opt.isPendingFreeze()) { 3916 return; 3917 } 3918 3919 final ArrayList<ProcessRecord> processes = mTmpProcessList; 3920 final ActiveUids uids = mTmpUidRecords; 3921 mTmpProcessSet.add(app); 3922 collectReachableProcessesLocked(mTmpProcessSet, processes, uids); 3923 mTmpProcessSet.clear(); 3924 // Now processes contains app's downstream and app 3925 final int size = processes.size(); 3926 for (int i = 0; i < size; i++) { 3927 ProcessRecord proc = processes.get(i); 3928 mCachedAppOptimizer.unfreezeTemporarily(proc, reason); 3929 } 3930 processes.clear(); 3931 } 3932 3933 @GuardedBy("mService") onProcessEndLocked(@onNull ProcessRecord app)3934 void onProcessEndLocked(@NonNull ProcessRecord app) { 3935 // Empty, the OomAdjusterModernImpl will have an implementation. 3936 } 3937 3938 /** 3939 * Called when the process state is changed outside of the OomAdjuster. 3940 */ 3941 @GuardedBy("mService") onProcessStateChanged(@onNull ProcessRecord app, int prevProcState)3942 void onProcessStateChanged(@NonNull ProcessRecord app, int prevProcState) { 3943 // Empty, the OomAdjusterModernImpl will have an implementation. 3944 } 3945 3946 /** 3947 * Called when the oom adj is changed outside of the OomAdjuster. 3948 */ 3949 @GuardedBy("mService") onProcessOomAdjChanged(@onNull ProcessRecord app, int prevAdj)3950 void onProcessOomAdjChanged(@NonNull ProcessRecord app, int prevAdj) { 3951 // Empty, the OomAdjusterModernImpl will have an implementation. 3952 } 3953 3954 @VisibleForTesting resetInternal()3955 void resetInternal() { 3956 // Empty, the OomAdjusterModernImpl will have an implementation. 3957 } 3958 3959 @GuardedBy("mService") getInitialAdj(@onNull ProcessRecord app)3960 protected int getInitialAdj(@NonNull ProcessRecord app) { 3961 return app.mState.getCurAdj(); 3962 } 3963 3964 @GuardedBy("mService") getInitialProcState(@onNull ProcessRecord app)3965 protected int getInitialProcState(@NonNull ProcessRecord app) { 3966 return app.mState.getCurProcState(); 3967 } 3968 3969 @GuardedBy("mService") getInitialCapability(@onNull ProcessRecord app)3970 protected int getInitialCapability(@NonNull ProcessRecord app) { 3971 return app.mState.getCurCapability(); 3972 } 3973 3974 @GuardedBy("mService") getInitialIsCurBoundByNonBgRestrictedApp(@onNull ProcessRecord app)3975 protected boolean getInitialIsCurBoundByNonBgRestrictedApp(@NonNull ProcessRecord app) { 3976 // The caller will set the initial value in this implementation. 3977 return app.mState.isCurBoundByNonBgRestrictedApp(); 3978 } 3979 3980 /** 3981 * Evaluate the service connection, return {@code true} if the client will change the state 3982 * of the service host process by the given connection. 3983 */ 3984 @GuardedBy("mService") evaluateServiceConnectionAdd(ProcessRecord client, ProcessRecord app, ConnectionRecord cr)3985 boolean evaluateServiceConnectionAdd(ProcessRecord client, ProcessRecord app, 3986 ConnectionRecord cr) { 3987 if (evaluateConnectionPrelude(client, app)) { 3988 return true; 3989 } 3990 if (app.getSetAdj() <= client.getSetAdj() 3991 && app.getSetProcState() <= client.getSetProcState() 3992 && ((app.getSetCapability() & client.getSetCapability()) 3993 == client.getSetCapability() 3994 || cr.notHasFlag(Context.BIND_INCLUDE_CAPABILITIES 3995 | Context.BIND_BYPASS_USER_NETWORK_RESTRICTIONS))) { 3996 // The service host process has better states than the client, so no change. 3997 return false; 3998 } 3999 // Take a dry run of the computeServiceHostOomAdjLSP, this would't be expensive 4000 // since it's only evaluating one service connection. 4001 return computeServiceHostOomAdjLSP(cr, app, client, mInjector.getUptimeMillis(), 4002 mService.getTopApp(), false, false, false, OOM_ADJ_REASON_NONE, 4003 CACHED_APP_MIN_ADJ, false, true /* dryRun */); 4004 } 4005 4006 @GuardedBy("mService") evaluateServiceConnectionRemoval(ProcessRecord client, ProcessRecord app, ConnectionRecord cr)4007 boolean evaluateServiceConnectionRemoval(ProcessRecord client, ProcessRecord app, 4008 ConnectionRecord cr) { 4009 if (evaluateConnectionPrelude(client, app)) { 4010 return true; 4011 } 4012 4013 if (app.getSetAdj() < client.getSetAdj() 4014 && app.getSetProcState() < client.getSetProcState()) { 4015 // The service host process has better states than the client. 4016 if (((app.getSetCapability() & client.getSetCapability()) == PROCESS_CAPABILITY_NONE) 4017 || cr.notHasFlag(Context.BIND_INCLUDE_CAPABILITIES 4018 | Context.BIND_BYPASS_USER_NETWORK_RESTRICTIONS)) { 4019 // The service host app doesn't get any capabilities from the client. 4020 return false; 4021 } 4022 } 4023 return true; 4024 } 4025 4026 @GuardedBy("mService") evaluateProviderConnectionAdd(ProcessRecord client, ProcessRecord app)4027 boolean evaluateProviderConnectionAdd(ProcessRecord client, ProcessRecord app) { 4028 if (evaluateConnectionPrelude(client, app)) { 4029 return true; 4030 } 4031 if (app.getSetAdj() <= client.getSetAdj() 4032 && app.getSetProcState() <= client.getSetProcState()) { 4033 // The provider host process has better states than the client, so no change. 4034 return false; 4035 } 4036 return computeProviderHostOomAdjLSP(null, app, client, mInjector.getUptimeMillis(), 4037 mService.getTopApp(), false, false, false, OOM_ADJ_REASON_NONE, CACHED_APP_MIN_ADJ, 4038 false, true /* dryRun */); 4039 } 4040 4041 @GuardedBy("mService") evaluateProviderConnectionRemoval(ProcessRecord client, ProcessRecord app)4042 boolean evaluateProviderConnectionRemoval(ProcessRecord client, ProcessRecord app) { 4043 if (evaluateConnectionPrelude(client, app)) { 4044 return true; 4045 } 4046 if (app.getSetAdj() < client.getSetAdj() 4047 && app.getSetProcState() < client.getSetProcState()) { 4048 // The provider host process has better states than the client, so no change. 4049 return false; 4050 } 4051 return true; 4052 } 4053 evaluateConnectionPrelude(ProcessRecord client, ProcessRecord app)4054 private boolean evaluateConnectionPrelude(ProcessRecord client, ProcessRecord app) { 4055 if (client == null || app == null) { 4056 return true; 4057 } 4058 if (app.isSdkSandbox || app.isolated || app.isKilledByAm() || app.isKilled()) { 4059 // Let's always re-evaluate them for now. 4060 return true; 4061 } 4062 return false; 4063 } 4064 4065 @GuardedBy("mService") maybeSetProcessFollowUpUpdateLocked(ProcessRecord proc, long updateUptimeMs, long now)4066 private void maybeSetProcessFollowUpUpdateLocked(ProcessRecord proc, 4067 long updateUptimeMs, long now) { 4068 if (!Flags.followUpOomadjUpdates()) { 4069 return; 4070 } 4071 if (updateUptimeMs <= now) { 4072 // Time sensitive period has already passed. No need to schedule a follow up. 4073 return; 4074 } 4075 4076 mFollowUpUpdateSet.add(proc); 4077 proc.mState.setFollowupUpdateUptimeMs(updateUptimeMs); 4078 4079 scheduleFollowUpOomAdjusterUpdateLocked(updateUptimeMs, now); 4080 } 4081 4082 4083 @GuardedBy("mService") scheduleFollowUpOomAdjusterUpdateLocked(long updateUptimeMs, long now)4084 private void scheduleFollowUpOomAdjusterUpdateLocked(long updateUptimeMs, 4085 long now) { 4086 if (updateUptimeMs + mConstants.FOLLOW_UP_OOMADJ_UPDATE_WAIT_DURATION 4087 >= mNextFollowUpUpdateUptimeMs) { 4088 // Update time is too close or later than the next follow up update. 4089 return; 4090 } 4091 if (updateUptimeMs < now + mConstants.FOLLOW_UP_OOMADJ_UPDATE_WAIT_DURATION) { 4092 // Use a minimum delay for the follow up to possibly batch multiple process 4093 // evaluations and avoid rapid updates. 4094 updateUptimeMs = now + mConstants.FOLLOW_UP_OOMADJ_UPDATE_WAIT_DURATION; 4095 } 4096 4097 // Schedulate a follow up update. Don't bother deleting existing handler messages, they 4098 // will be cleared during the message while no locks are being held. 4099 mNextFollowUpUpdateUptimeMs = updateUptimeMs; 4100 mService.mHandler.sendEmptyMessageAtTime(FOLLOW_UP_OOMADJUSTER_UPDATE_MSG, 4101 mNextFollowUpUpdateUptimeMs); 4102 } 4103 } 4104