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