1 /* 2 * Copyright (C) 2011 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_STATE_CACHED_ACTIVITY; 20 import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; 21 import static android.app.ActivityThread.PROC_START_SEQ_IDENT; 22 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AUTO; 23 import static android.os.Process.SYSTEM_UID; 24 import static android.os.Process.THREAD_PRIORITY_BACKGROUND; 25 import static android.os.Process.getFreeMemory; 26 import static android.os.Process.getTotalMemory; 27 import static android.os.Process.killProcessQuiet; 28 import static android.os.Process.startWebView; 29 30 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU; 31 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES; 32 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS; 33 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS; 34 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; 35 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; 36 import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_DELAY_MS; 37 import static com.android.server.am.ActivityManagerService.KILL_APP_ZYGOTE_MSG; 38 import static com.android.server.am.ActivityManagerService.PERSISTENT_MASK; 39 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT; 40 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_MSG; 41 import static com.android.server.am.ActivityManagerService.PROC_START_TIMEOUT_WITH_WRAPPER; 42 import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS; 43 import static com.android.server.am.ActivityManagerService.TAG_LRU; 44 import static com.android.server.am.ActivityManagerService.TAG_PROCESSES; 45 import static com.android.server.am.ActivityManagerService.TAG_PSS; 46 import static com.android.server.am.ActivityManagerService.TAG_UID_OBSERVERS; 47 48 import android.app.ActivityManager; 49 import android.app.ActivityThread; 50 import android.app.AppGlobals; 51 import android.app.AppProtoEnums; 52 import android.app.IApplicationThread; 53 import android.content.ComponentName; 54 import android.content.Context; 55 import android.content.Intent; 56 import android.content.pm.ApplicationInfo; 57 import android.content.pm.IPackageManager; 58 import android.content.res.Resources; 59 import android.graphics.Point; 60 import android.net.LocalSocket; 61 import android.net.LocalSocketAddress; 62 import android.os.AppZygote; 63 import android.os.Binder; 64 import android.os.Build; 65 import android.os.Bundle; 66 import android.os.Handler; 67 import android.os.IBinder; 68 import android.os.Looper; 69 import android.os.Message; 70 import android.os.Process; 71 import android.os.RemoteException; 72 import android.os.StrictMode; 73 import android.os.SystemClock; 74 import android.os.SystemProperties; 75 import android.os.Trace; 76 import android.os.UserHandle; 77 import android.os.storage.StorageManager; 78 import android.os.storage.StorageManagerInternal; 79 import android.text.TextUtils; 80 import android.util.ArrayMap; 81 import android.util.EventLog; 82 import android.util.LongSparseArray; 83 import android.util.Slog; 84 import android.util.SparseArray; 85 import android.util.SparseBooleanArray; 86 import android.util.StatsLog; 87 import android.view.Display; 88 89 import com.android.internal.annotations.GuardedBy; 90 import com.android.internal.annotations.VisibleForTesting; 91 import com.android.internal.app.ProcessMap; 92 import com.android.internal.app.procstats.ProcessStats; 93 import com.android.internal.os.Zygote; 94 import com.android.internal.util.ArrayUtils; 95 import com.android.internal.util.MemInfoReader; 96 import com.android.server.LocalServices; 97 import com.android.server.ServiceThread; 98 import com.android.server.Watchdog; 99 import com.android.server.pm.dex.DexManager; 100 import com.android.server.wm.ActivityServiceConnectionsHolder; 101 import com.android.server.wm.WindowManagerService; 102 103 import dalvik.system.VMRuntime; 104 105 import libcore.io.IoUtils; 106 107 import java.io.File; 108 import java.io.IOException; 109 import java.io.InputStream; 110 import java.io.OutputStream; 111 import java.io.PrintWriter; 112 import java.nio.ByteBuffer; 113 import java.util.ArrayList; 114 import java.util.Arrays; 115 import java.util.BitSet; 116 import java.util.List; 117 118 /** 119 * Activity manager code dealing with processes. 120 * 121 * Method naming convention: 122 * <ul> 123 * <li> Methods suffixed with "LS" should be called within the {@link #sLmkdSocketLock} lock. 124 * </ul> 125 */ 126 public final class ProcessList { 127 static final String TAG = TAG_WITH_CLASS_NAME ? "ProcessList" : TAG_AM; 128 129 // The minimum time we allow between crashes, for us to consider this 130 // application to be bad and stop and its services and reject broadcasts. 131 static final int MIN_CRASH_INTERVAL = 60 * 1000; 132 133 // OOM adjustments for processes in various states: 134 135 // Uninitialized value for any major or minor adj fields 136 static final int INVALID_ADJ = -10000; 137 138 // Adjustment used in certain places where we don't know it yet. 139 // (Generally this is something that is going to be cached, but we 140 // don't know the exact value in the cached range to assign yet.) 141 static final int UNKNOWN_ADJ = 1001; 142 143 // This is a process only hosting activities that are not visible, 144 // so it can be killed without any disruption. 145 static final int CACHED_APP_MAX_ADJ = 999; 146 static final int CACHED_APP_MIN_ADJ = 900; 147 148 // This is the oom_adj level that we allow to die first. This cannot be equal to 149 // CACHED_APP_MAX_ADJ unless processes are actively being assigned an oom_score_adj of 150 // CACHED_APP_MAX_ADJ. 151 static final int CACHED_APP_LMK_FIRST_ADJ = 950; 152 153 // Number of levels we have available for different service connection group importance 154 // levels. 155 static final int CACHED_APP_IMPORTANCE_LEVELS = 5; 156 157 // The B list of SERVICE_ADJ -- these are the old and decrepit 158 // services that aren't as shiny and interesting as the ones in the A list. 159 static final int SERVICE_B_ADJ = 800; 160 161 // This is the process of the previous application that the user was in. 162 // This process is kept above other things, because it is very common to 163 // switch back to the previous app. This is important both for recent 164 // task switch (toggling between the two top recent apps) as well as normal 165 // UI flow such as clicking on a URI in the e-mail app to view in the browser, 166 // and then pressing back to return to e-mail. 167 static final int PREVIOUS_APP_ADJ = 700; 168 169 // This is a process holding the home application -- we want to try 170 // avoiding killing it, even if it would normally be in the background, 171 // because the user interacts with it so much. 172 static final int HOME_APP_ADJ = 600; 173 174 // This is a process holding an application service -- killing it will not 175 // have much of an impact as far as the user is concerned. 176 static final int SERVICE_ADJ = 500; 177 178 // This is a process with a heavy-weight application. It is in the 179 // background, but we want to try to avoid killing it. Value set in 180 // system/rootdir/init.rc on startup. 181 static final int HEAVY_WEIGHT_APP_ADJ = 400; 182 183 // This is a process currently hosting a backup operation. Killing it 184 // is not entirely fatal but is generally a bad idea. 185 static final int BACKUP_APP_ADJ = 300; 186 187 // This is a process bound by the system (or other app) that's more important than services but 188 // not so perceptible that it affects the user immediately if killed. 189 static final int PERCEPTIBLE_LOW_APP_ADJ = 250; 190 191 // This is a process only hosting components that are perceptible to the 192 // user, and we really want to avoid killing them, but they are not 193 // immediately visible. An example is background music playback. 194 static final int PERCEPTIBLE_APP_ADJ = 200; 195 196 // This is a process only hosting activities that are visible to the 197 // user, so we'd prefer they don't disappear. 198 static final int VISIBLE_APP_ADJ = 100; 199 static final int VISIBLE_APP_LAYER_MAX = PERCEPTIBLE_APP_ADJ - VISIBLE_APP_ADJ - 1; 200 201 // This is a process that was recently TOP and moved to FGS. Continue to treat it almost 202 // like a foreground app for a while. 203 // @see TOP_TO_FGS_GRACE_PERIOD 204 static final int PERCEPTIBLE_RECENT_FOREGROUND_APP_ADJ = 50; 205 206 // This is the process running the current foreground app. We'd really 207 // rather not kill it! 208 static final int FOREGROUND_APP_ADJ = 0; 209 210 // This is a process that the system or a persistent process has bound to, 211 // and indicated it is important. 212 static final int PERSISTENT_SERVICE_ADJ = -700; 213 214 // This is a system persistent process, such as telephony. Definitely 215 // don't want to kill it, but doing so is not completely fatal. 216 static final int PERSISTENT_PROC_ADJ = -800; 217 218 // The system process runs at the default adjustment. 219 static final int SYSTEM_ADJ = -900; 220 221 // Special code for native processes that are not being managed by the system (so 222 // don't have an oom adj assigned by the system). 223 static final int NATIVE_ADJ = -1000; 224 225 // Memory pages are 4K. 226 static final int PAGE_SIZE = 4 * 1024; 227 228 // Activity manager's version of Process.THREAD_GROUP_BG_NONINTERACTIVE 229 static final int SCHED_GROUP_BACKGROUND = 0; 230 // Activity manager's version of Process.THREAD_GROUP_RESTRICTED 231 static final int SCHED_GROUP_RESTRICTED = 1; 232 // Activity manager's version of Process.THREAD_GROUP_DEFAULT 233 static final int SCHED_GROUP_DEFAULT = 2; 234 // Activity manager's version of Process.THREAD_GROUP_TOP_APP 235 public static final int SCHED_GROUP_TOP_APP = 3; 236 // Activity manager's version of Process.THREAD_GROUP_TOP_APP 237 // Disambiguate between actual top app and processes bound to the top app 238 static final int SCHED_GROUP_TOP_APP_BOUND = 4; 239 240 // The minimum number of cached apps we want to be able to keep around, 241 // without empty apps being able to push them out of memory. 242 static final int MIN_CACHED_APPS = 2; 243 244 // We allow empty processes to stick around for at most 30 minutes. 245 static final long MAX_EMPTY_TIME = 30 * 60 * 1000; 246 247 // Threshold of number of cached+empty where we consider memory critical. 248 static final int TRIM_CRITICAL_THRESHOLD = 3; 249 250 // Threshold of number of cached+empty where we consider memory critical. 251 static final int TRIM_LOW_THRESHOLD = 5; 252 253 // If true, then we pass the flag to ART to load the app image startup cache. 254 private static final String PROPERTY_USE_APP_IMAGE_STARTUP_CACHE = 255 "persist.device_config.runtime_native.use_app_image_startup_cache"; 256 257 // Low Memory Killer Daemon command codes. 258 // These must be kept in sync with the definitions in lmkd.c 259 // 260 // LMK_TARGET <minfree> <minkillprio> ... (up to 6 pairs) 261 // LMK_PROCPRIO <pid> <uid> <prio> 262 // LMK_PROCREMOVE <pid> 263 // LMK_PROCPURGE 264 // LMK_GETKILLCNT 265 static final byte LMK_TARGET = 0; 266 static final byte LMK_PROCPRIO = 1; 267 static final byte LMK_PROCREMOVE = 2; 268 static final byte LMK_PROCPURGE = 3; 269 static final byte LMK_GETKILLCNT = 4; 270 271 ActivityManagerService mService = null; 272 273 // To kill process groups asynchronously 274 static KillHandler sKillHandler = null; 275 static ServiceThread sKillThread = null; 276 277 // These are the various interesting memory levels that we will give to 278 // the OOM killer. Note that the OOM killer only supports 6 slots, so we 279 // can't give it a different value for every possible kind of process. 280 private final int[] mOomAdj = new int[] { 281 FOREGROUND_APP_ADJ, VISIBLE_APP_ADJ, PERCEPTIBLE_APP_ADJ, 282 PERCEPTIBLE_LOW_APP_ADJ, CACHED_APP_MIN_ADJ, CACHED_APP_LMK_FIRST_ADJ 283 }; 284 // These are the low-end OOM level limits. This is appropriate for an 285 // HVGA or smaller phone with less than 512MB. Values are in KB. 286 private final int[] mOomMinFreeLow = new int[] { 287 12288, 18432, 24576, 288 36864, 43008, 49152 289 }; 290 // These are the high-end OOM level limits. This is appropriate for a 291 // 1280x800 or larger screen with around 1GB RAM. Values are in KB. 292 private final int[] mOomMinFreeHigh = new int[] { 293 73728, 92160, 110592, 294 129024, 147456, 184320 295 }; 296 // The actual OOM killer memory levels we are using. 297 private final int[] mOomMinFree = new int[mOomAdj.length]; 298 299 private final long mTotalMemMb; 300 301 private long mCachedRestoreLevel; 302 303 private boolean mHaveDisplaySize; 304 305 private static Object sLmkdSocketLock = new Object(); 306 307 @GuardedBy("sLmkdSocketLock") 308 private static LocalSocket sLmkdSocket; 309 310 @GuardedBy("sLmkdSocketLock") 311 private static OutputStream sLmkdOutputStream; 312 313 @GuardedBy("sLmkdSocketLock") 314 private static InputStream sLmkdInputStream; 315 316 /** 317 * Temporary to avoid allocations. Protected by main lock. 318 */ 319 @GuardedBy("mService") 320 final StringBuilder mStringBuilder = new StringBuilder(256); 321 322 /** 323 * A global counter for generating sequence numbers. 324 * This value will be used when incrementing sequence numbers in individual uidRecords. 325 * 326 * Having a global counter ensures that seq numbers are monotonically increasing for a 327 * particular uid even when the uidRecord is re-created. 328 */ 329 @GuardedBy("mService") 330 @VisibleForTesting 331 long mProcStateSeqCounter = 0; 332 333 /** 334 * A global counter for generating sequence numbers to uniquely identify pending process starts. 335 */ 336 @GuardedBy("mService") 337 private long mProcStartSeqCounter = 0; 338 339 /** 340 * Contains {@link ProcessRecord} objects for pending process starts. 341 * 342 * Mapping: {@link #mProcStartSeqCounter} -> {@link ProcessRecord} 343 */ 344 @GuardedBy("mService") 345 final LongSparseArray<ProcessRecord> mPendingStarts = new LongSparseArray<>(); 346 347 /** 348 * List of running applications, sorted by recent usage. 349 * The first entry in the list is the least recently used. 350 */ 351 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>(); 352 353 /** 354 * Where in mLruProcesses that the processes hosting activities start. 355 */ 356 int mLruProcessActivityStart = 0; 357 358 /** 359 * Where in mLruProcesses that the processes hosting services start. 360 * This is after (lower index) than mLruProcessesActivityStart. 361 */ 362 int mLruProcessServiceStart = 0; 363 364 /** 365 * Current sequence id for process LRU updating. 366 */ 367 int mLruSeq = 0; 368 369 ActiveUids mActiveUids; 370 371 /** 372 * The currently running isolated processes. 373 */ 374 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<>(); 375 376 /** 377 * The currently running application zygotes. 378 */ 379 final ProcessMap<AppZygote> mAppZygotes = new ProcessMap<AppZygote>(); 380 381 /** 382 * The processes that are forked off an application zygote. 383 */ 384 final ArrayMap<AppZygote, ArrayList<ProcessRecord>> mAppZygoteProcesses = 385 new ArrayMap<AppZygote, ArrayList<ProcessRecord>>(); 386 387 final class IsolatedUidRange { 388 @VisibleForTesting 389 public final int mFirstUid; 390 @VisibleForTesting 391 public final int mLastUid; 392 393 @GuardedBy("ProcessList.this.mService") 394 private final SparseBooleanArray mUidUsed = new SparseBooleanArray(); 395 396 @GuardedBy("ProcessList.this.mService") 397 private int mNextUid; 398 399 IsolatedUidRange(int firstUid, int lastUid) { 400 mFirstUid = firstUid; 401 mLastUid = lastUid; 402 mNextUid = firstUid; 403 } 404 405 @GuardedBy("ProcessList.this.mService") 406 int allocateIsolatedUidLocked(int userId) { 407 int uid; 408 int stepsLeft = (mLastUid - mFirstUid + 1); 409 for (int i = 0; i < stepsLeft; ++i) { 410 if (mNextUid < mFirstUid || mNextUid > mLastUid) { 411 mNextUid = mFirstUid; 412 } 413 uid = UserHandle.getUid(userId, mNextUid); 414 mNextUid++; 415 if (!mUidUsed.get(uid, false)) { 416 mUidUsed.put(uid, true); 417 return uid; 418 } 419 } 420 return -1; 421 } 422 423 @GuardedBy("ProcessList.this.mService") 424 void freeIsolatedUidLocked(int uid) { 425 // Strip out userId 426 final int appId = UserHandle.getAppId(uid); 427 mUidUsed.delete(appId); 428 } 429 }; 430 431 /** 432 * A class that allocates ranges of isolated UIDs per application, and keeps track of them. 433 */ 434 final class IsolatedUidRangeAllocator { 435 private final int mFirstUid; 436 private final int mNumUidRanges; 437 private final int mNumUidsPerRange; 438 /** 439 * We map the uid range [mFirstUid, mFirstUid + mNumUidRanges * mNumUidsPerRange) 440 * back to an underlying bitset of [0, mNumUidRanges) and allocate out of that. 441 */ 442 @GuardedBy("ProcessList.this.mService") 443 private final BitSet mAvailableUidRanges; 444 @GuardedBy("ProcessList.this.mService") 445 private final ProcessMap<IsolatedUidRange> mAppRanges = new ProcessMap<IsolatedUidRange>(); 446 447 IsolatedUidRangeAllocator(int firstUid, int lastUid, int numUidsPerRange) { 448 mFirstUid = firstUid; 449 mNumUidsPerRange = numUidsPerRange; 450 mNumUidRanges = (lastUid - firstUid + 1) / numUidsPerRange; 451 mAvailableUidRanges = new BitSet(mNumUidRanges); 452 // Mark all as available 453 mAvailableUidRanges.set(0, mNumUidRanges); 454 } 455 456 @GuardedBy("ProcessList.this.mService") 457 IsolatedUidRange getIsolatedUidRangeLocked(String processName, int uid) { 458 return mAppRanges.get(processName, uid); 459 } 460 461 @GuardedBy("ProcessList.this.mService") 462 IsolatedUidRange getOrCreateIsolatedUidRangeLocked(String processName, int uid) { 463 IsolatedUidRange range = getIsolatedUidRangeLocked(processName, uid); 464 if (range == null) { 465 int uidRangeIndex = mAvailableUidRanges.nextSetBit(0); 466 if (uidRangeIndex < 0) { 467 // No free range 468 return null; 469 } 470 mAvailableUidRanges.clear(uidRangeIndex); 471 int actualUid = mFirstUid + uidRangeIndex * mNumUidsPerRange; 472 range = new IsolatedUidRange(actualUid, actualUid + mNumUidsPerRange - 1); 473 mAppRanges.put(processName, uid, range); 474 } 475 return range; 476 } 477 478 @GuardedBy("ProcessList.this.mService") 479 void freeUidRangeLocked(ApplicationInfo info) { 480 // Find the UID range 481 IsolatedUidRange range = mAppRanges.get(info.processName, info.uid); 482 if (range != null) { 483 // Map back to starting uid 484 final int uidRangeIndex = (range.mFirstUid - mFirstUid) / mNumUidsPerRange; 485 // Mark it as available in the underlying bitset 486 mAvailableUidRanges.set(uidRangeIndex); 487 // And the map 488 mAppRanges.remove(info.processName, info.uid); 489 } 490 } 491 } 492 493 /** 494 * The available isolated UIDs for processes that are not spawned from an application zygote. 495 */ 496 @VisibleForTesting 497 IsolatedUidRange mGlobalIsolatedUids = new IsolatedUidRange(Process.FIRST_ISOLATED_UID, 498 Process.LAST_ISOLATED_UID); 499 500 /** 501 * An allocator for isolated UID ranges for apps that use an application zygote. 502 */ 503 @VisibleForTesting 504 IsolatedUidRangeAllocator mAppIsolatedUidRangeAllocator = 505 new IsolatedUidRangeAllocator(Process.FIRST_APP_ZYGOTE_ISOLATED_UID, 506 Process.LAST_APP_ZYGOTE_ISOLATED_UID, Process.NUM_UIDS_PER_APP_ZYGOTE); 507 508 /** 509 * Processes that are being forcibly torn down. 510 */ 511 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>(); 512 513 /** 514 * All of the applications we currently have running organized by name. 515 * The keys are strings of the application package name (as 516 * returned by the package manager), and the keys are ApplicationRecord 517 * objects. 518 */ 519 final MyProcessMap mProcessNames = new MyProcessMap(); 520 521 final class MyProcessMap extends ProcessMap<ProcessRecord> { 522 @Override 523 public ProcessRecord put(String name, int uid, ProcessRecord value) { 524 final ProcessRecord r = super.put(name, uid, value); 525 mService.mAtmInternal.onProcessAdded(r.getWindowProcessController()); 526 return r; 527 } 528 529 @Override 530 public ProcessRecord remove(String name, int uid) { 531 final ProcessRecord r = super.remove(name, uid); 532 mService.mAtmInternal.onProcessRemoved(name, uid); 533 return r; 534 } 535 } 536 537 final class KillHandler extends Handler { 538 static final int KILL_PROCESS_GROUP_MSG = 4000; 539 540 public KillHandler(Looper looper) { 541 super(looper, null, true); 542 } 543 544 @Override 545 public void handleMessage(Message msg) { 546 switch (msg.what) { 547 case KILL_PROCESS_GROUP_MSG: 548 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup"); 549 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */); 550 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 551 break; 552 553 default: 554 super.handleMessage(msg); 555 } 556 } 557 } 558 559 //////////////////// END FIELDS //////////////////// 560 561 ProcessList() { 562 MemInfoReader minfo = new MemInfoReader(); 563 minfo.readMemInfo(); 564 mTotalMemMb = minfo.getTotalSize()/(1024*1024); 565 updateOomLevels(0, 0, false); 566 } 567 568 void init(ActivityManagerService service, ActiveUids activeUids) { 569 mService = service; 570 mActiveUids = activeUids; 571 572 if (sKillHandler == null) { 573 sKillThread = new ServiceThread(TAG + ":kill", 574 THREAD_PRIORITY_BACKGROUND, true /* allowIo */); 575 sKillThread.start(); 576 sKillHandler = new KillHandler(sKillThread.getLooper()); 577 } 578 } 579 580 void applyDisplaySize(WindowManagerService wm) { 581 if (!mHaveDisplaySize) { 582 Point p = new Point(); 583 // TODO(multi-display): Compute based on sum of all connected displays' resolutions. 584 wm.getBaseDisplaySize(Display.DEFAULT_DISPLAY, p); 585 if (p.x != 0 && p.y != 0) { 586 updateOomLevels(p.x, p.y, true); 587 mHaveDisplaySize = true; 588 } 589 } 590 } 591 592 private void updateOomLevels(int displayWidth, int displayHeight, boolean write) { 593 // Scale buckets from avail memory: at 300MB we use the lowest values to 594 // 700MB or more for the top values. 595 float scaleMem = ((float) (mTotalMemMb - 350)) / (700 - 350); 596 597 // Scale buckets from screen size. 598 int minSize = 480 * 800; // 384000 599 int maxSize = 1280 * 800; // 1024000 230400 870400 .264 600 float scaleDisp = ((float)(displayWidth * displayHeight) - minSize) / (maxSize - minSize); 601 if (false) { 602 Slog.i("XXXXXX", "scaleMem=" + scaleMem); 603 Slog.i("XXXXXX", "scaleDisp=" + scaleDisp + " dw=" + displayWidth 604 + " dh=" + displayHeight); 605 } 606 607 float scale = scaleMem > scaleDisp ? scaleMem : scaleDisp; 608 if (scale < 0) scale = 0; 609 else if (scale > 1) scale = 1; 610 int minfree_adj = Resources.getSystem().getInteger( 611 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAdjust); 612 int minfree_abs = Resources.getSystem().getInteger( 613 com.android.internal.R.integer.config_lowMemoryKillerMinFreeKbytesAbsolute); 614 if (false) { 615 Slog.i("XXXXXX", "minfree_adj=" + minfree_adj + " minfree_abs=" + minfree_abs); 616 } 617 618 final boolean is64bit = Build.SUPPORTED_64_BIT_ABIS.length > 0; 619 620 for (int i = 0; i < mOomAdj.length; i++) { 621 int low = mOomMinFreeLow[i]; 622 int high = mOomMinFreeHigh[i]; 623 if (is64bit) { 624 // Increase the high min-free levels for cached processes for 64-bit 625 if (i == 4) high = (high * 3) / 2; 626 else if (i == 5) high = (high * 7) / 4; 627 } 628 mOomMinFree[i] = (int)(low + ((high - low) * scale)); 629 } 630 631 if (minfree_abs >= 0) { 632 for (int i = 0; i < mOomAdj.length; i++) { 633 mOomMinFree[i] = (int)((float)minfree_abs * mOomMinFree[i] 634 / mOomMinFree[mOomAdj.length - 1]); 635 } 636 } 637 638 if (minfree_adj != 0) { 639 for (int i = 0; i < mOomAdj.length; i++) { 640 mOomMinFree[i] += (int)((float) minfree_adj * mOomMinFree[i] 641 / mOomMinFree[mOomAdj.length - 1]); 642 if (mOomMinFree[i] < 0) { 643 mOomMinFree[i] = 0; 644 } 645 } 646 } 647 648 // The maximum size we will restore a process from cached to background, when under 649 // memory duress, is 1/3 the size we have reserved for kernel caches and other overhead 650 // before killing background processes. 651 mCachedRestoreLevel = (getMemLevel(ProcessList.CACHED_APP_MAX_ADJ) / 1024) / 3; 652 653 // Ask the kernel to try to keep enough memory free to allocate 3 full 654 // screen 32bpp buffers without entering direct reclaim. 655 int reserve = displayWidth * displayHeight * 4 * 3 / 1024; 656 int reserve_adj = Resources.getSystem().getInteger( 657 com.android.internal.R.integer.config_extraFreeKbytesAdjust); 658 int reserve_abs = Resources.getSystem().getInteger( 659 com.android.internal.R.integer.config_extraFreeKbytesAbsolute); 660 661 if (reserve_abs >= 0) { 662 reserve = reserve_abs; 663 } 664 665 if (reserve_adj != 0) { 666 reserve += reserve_adj; 667 if (reserve < 0) { 668 reserve = 0; 669 } 670 } 671 672 if (write) { 673 ByteBuffer buf = ByteBuffer.allocate(4 * (2 * mOomAdj.length + 1)); 674 buf.putInt(LMK_TARGET); 675 for (int i = 0; i < mOomAdj.length; i++) { 676 buf.putInt((mOomMinFree[i] * 1024)/PAGE_SIZE); 677 buf.putInt(mOomAdj[i]); 678 } 679 680 writeLmkd(buf, null); 681 SystemProperties.set("sys.sysctl.extra_free_kbytes", Integer.toString(reserve)); 682 } 683 // GB: 2048,3072,4096,6144,7168,8192 684 // HC: 8192,10240,12288,14336,16384,20480 685 } 686 687 public static int computeEmptyProcessLimit(int totalProcessLimit) { 688 return totalProcessLimit/2; 689 } 690 691 private static String buildOomTag(String prefix, String compactPrefix, String space, int val, 692 int base, boolean compact) { 693 final int diff = val - base; 694 if (diff == 0) { 695 if (compact) { 696 return compactPrefix; 697 } 698 if (space == null) return prefix; 699 return prefix + space; 700 } 701 if (diff < 10) { 702 return prefix + (compact ? "+" : "+ ") + Integer.toString(diff); 703 } 704 return prefix + "+" + Integer.toString(diff); 705 } 706 707 public static String makeOomAdjString(int setAdj, boolean compact) { 708 if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 709 return buildOomTag("cch", "cch", " ", setAdj, 710 ProcessList.CACHED_APP_MIN_ADJ, compact); 711 } else if (setAdj >= ProcessList.SERVICE_B_ADJ) { 712 return buildOomTag("svcb ", "svcb", null, setAdj, 713 ProcessList.SERVICE_B_ADJ, compact); 714 } else if (setAdj >= ProcessList.PREVIOUS_APP_ADJ) { 715 return buildOomTag("prev ", "prev", null, setAdj, 716 ProcessList.PREVIOUS_APP_ADJ, compact); 717 } else if (setAdj >= ProcessList.HOME_APP_ADJ) { 718 return buildOomTag("home ", "home", null, setAdj, 719 ProcessList.HOME_APP_ADJ, compact); 720 } else if (setAdj >= ProcessList.SERVICE_ADJ) { 721 return buildOomTag("svc ", "svc", null, setAdj, 722 ProcessList.SERVICE_ADJ, compact); 723 } else if (setAdj >= ProcessList.HEAVY_WEIGHT_APP_ADJ) { 724 return buildOomTag("hvy ", "hvy", null, setAdj, 725 ProcessList.HEAVY_WEIGHT_APP_ADJ, compact); 726 } else if (setAdj >= ProcessList.BACKUP_APP_ADJ) { 727 return buildOomTag("bkup ", "bkup", null, setAdj, 728 ProcessList.BACKUP_APP_ADJ, compact); 729 } else if (setAdj >= ProcessList.PERCEPTIBLE_LOW_APP_ADJ) { 730 return buildOomTag("prcl ", "prcl", null, setAdj, 731 ProcessList.PERCEPTIBLE_LOW_APP_ADJ, compact); 732 } else if (setAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) { 733 return buildOomTag("prcp ", "prcp", null, setAdj, 734 ProcessList.PERCEPTIBLE_APP_ADJ, compact); 735 } else if (setAdj >= ProcessList.VISIBLE_APP_ADJ) { 736 return buildOomTag("vis", "vis", " ", setAdj, 737 ProcessList.VISIBLE_APP_ADJ, compact); 738 } else if (setAdj >= ProcessList.FOREGROUND_APP_ADJ) { 739 return buildOomTag("fore ", "fore", null, setAdj, 740 ProcessList.FOREGROUND_APP_ADJ, compact); 741 } else if (setAdj >= ProcessList.PERSISTENT_SERVICE_ADJ) { 742 return buildOomTag("psvc ", "psvc", null, setAdj, 743 ProcessList.PERSISTENT_SERVICE_ADJ, compact); 744 } else if (setAdj >= ProcessList.PERSISTENT_PROC_ADJ) { 745 return buildOomTag("pers ", "pers", null, setAdj, 746 ProcessList.PERSISTENT_PROC_ADJ, compact); 747 } else if (setAdj >= ProcessList.SYSTEM_ADJ) { 748 return buildOomTag("sys ", "sys", null, setAdj, 749 ProcessList.SYSTEM_ADJ, compact); 750 } else if (setAdj >= ProcessList.NATIVE_ADJ) { 751 return buildOomTag("ntv ", "ntv", null, setAdj, 752 ProcessList.NATIVE_ADJ, compact); 753 } else { 754 return Integer.toString(setAdj); 755 } 756 } 757 758 public static String makeProcStateString(int curProcState) { 759 String procState; 760 switch (curProcState) { 761 case ActivityManager.PROCESS_STATE_PERSISTENT: 762 procState = "PER "; 763 break; 764 case ActivityManager.PROCESS_STATE_PERSISTENT_UI: 765 procState = "PERU"; 766 break; 767 case ActivityManager.PROCESS_STATE_TOP: 768 procState = "TOP "; 769 break; 770 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION: 771 procState = "FGSL"; 772 break; 773 case ActivityManager.PROCESS_STATE_BOUND_TOP: 774 procState = "BTOP"; 775 break; 776 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE: 777 procState = "FGS "; 778 break; 779 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE: 780 procState = "BFGS"; 781 break; 782 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 783 procState = "IMPF"; 784 break; 785 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 786 procState = "IMPB"; 787 break; 788 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND: 789 procState = "TRNB"; 790 break; 791 case ActivityManager.PROCESS_STATE_BACKUP: 792 procState = "BKUP"; 793 break; 794 case ActivityManager.PROCESS_STATE_SERVICE: 795 procState = "SVC "; 796 break; 797 case ActivityManager.PROCESS_STATE_RECEIVER: 798 procState = "RCVR"; 799 break; 800 case ActivityManager.PROCESS_STATE_TOP_SLEEPING: 801 procState = "TPSL"; 802 break; 803 case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT: 804 procState = "HVY "; 805 break; 806 case ActivityManager.PROCESS_STATE_HOME: 807 procState = "HOME"; 808 break; 809 case ActivityManager.PROCESS_STATE_LAST_ACTIVITY: 810 procState = "LAST"; 811 break; 812 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 813 procState = "CAC "; 814 break; 815 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 816 procState = "CACC"; 817 break; 818 case ActivityManager.PROCESS_STATE_CACHED_RECENT: 819 procState = "CRE "; 820 break; 821 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 822 procState = "CEM "; 823 break; 824 case ActivityManager.PROCESS_STATE_NONEXISTENT: 825 procState = "NONE"; 826 break; 827 default: 828 procState = "??"; 829 break; 830 } 831 return procState; 832 } 833 834 public static int makeProcStateProtoEnum(int curProcState) { 835 switch (curProcState) { 836 case ActivityManager.PROCESS_STATE_PERSISTENT: 837 return AppProtoEnums.PROCESS_STATE_PERSISTENT; 838 case ActivityManager.PROCESS_STATE_PERSISTENT_UI: 839 return AppProtoEnums.PROCESS_STATE_PERSISTENT_UI; 840 case ActivityManager.PROCESS_STATE_TOP: 841 return AppProtoEnums.PROCESS_STATE_TOP; 842 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION: 843 return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE; 844 case ActivityManager.PROCESS_STATE_BOUND_TOP: 845 return AppProtoEnums.PROCESS_STATE_BOUND_TOP; 846 case ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE: 847 return AppProtoEnums.PROCESS_STATE_FOREGROUND_SERVICE; 848 case ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE: 849 return AppProtoEnums.PROCESS_STATE_BOUND_FOREGROUND_SERVICE; 850 case ActivityManager.PROCESS_STATE_TOP_SLEEPING: 851 return AppProtoEnums.PROCESS_STATE_TOP_SLEEPING; 852 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND: 853 return AppProtoEnums.PROCESS_STATE_IMPORTANT_FOREGROUND; 854 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND: 855 return AppProtoEnums.PROCESS_STATE_IMPORTANT_BACKGROUND; 856 case ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND: 857 return AppProtoEnums.PROCESS_STATE_TRANSIENT_BACKGROUND; 858 case ActivityManager.PROCESS_STATE_BACKUP: 859 return AppProtoEnums.PROCESS_STATE_BACKUP; 860 case ActivityManager.PROCESS_STATE_HEAVY_WEIGHT: 861 return AppProtoEnums.PROCESS_STATE_HEAVY_WEIGHT; 862 case ActivityManager.PROCESS_STATE_SERVICE: 863 return AppProtoEnums.PROCESS_STATE_SERVICE; 864 case ActivityManager.PROCESS_STATE_RECEIVER: 865 return AppProtoEnums.PROCESS_STATE_RECEIVER; 866 case ActivityManager.PROCESS_STATE_HOME: 867 return AppProtoEnums.PROCESS_STATE_HOME; 868 case ActivityManager.PROCESS_STATE_LAST_ACTIVITY: 869 return AppProtoEnums.PROCESS_STATE_LAST_ACTIVITY; 870 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY: 871 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY; 872 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT: 873 return AppProtoEnums.PROCESS_STATE_CACHED_ACTIVITY_CLIENT; 874 case ActivityManager.PROCESS_STATE_CACHED_RECENT: 875 return AppProtoEnums.PROCESS_STATE_CACHED_RECENT; 876 case ActivityManager.PROCESS_STATE_CACHED_EMPTY: 877 return AppProtoEnums.PROCESS_STATE_CACHED_EMPTY; 878 case ActivityManager.PROCESS_STATE_NONEXISTENT: 879 return AppProtoEnums.PROCESS_STATE_NONEXISTENT; 880 case ActivityManager.PROCESS_STATE_UNKNOWN: 881 return AppProtoEnums.PROCESS_STATE_UNKNOWN; 882 default: 883 return AppProtoEnums.PROCESS_STATE_UNKNOWN_TO_PROTO; 884 } 885 } 886 887 public static void appendRamKb(StringBuilder sb, long ramKb) { 888 for (int j = 0, fact = 10; j < 6; j++, fact *= 10) { 889 if (ramKb < fact) { 890 sb.append(' '); 891 } 892 } 893 sb.append(ramKb); 894 } 895 896 // How long after a state change that it is safe to collect PSS without it being dirty. 897 public static final int PSS_SAFE_TIME_FROM_STATE_CHANGE = 1000; 898 899 // The minimum time interval after a state change it is safe to collect PSS. 900 public static final int PSS_MIN_TIME_FROM_STATE_CHANGE = 15*1000; 901 902 // The maximum amount of time we want to go between PSS collections. 903 public static final int PSS_MAX_INTERVAL = 60*60*1000; 904 905 // The minimum amount of time between successive PSS requests for *all* processes. 906 public static final int PSS_ALL_INTERVAL = 20*60*1000; 907 908 // The amount of time until PSS when a persistent process first appears. 909 private static final int PSS_FIRST_PERSISTENT_INTERVAL = 30*1000; 910 911 // The amount of time until PSS when a process first becomes top. 912 private static final int PSS_FIRST_TOP_INTERVAL = 10*1000; 913 914 // The amount of time until PSS when a process first goes into the background. 915 private static final int PSS_FIRST_BACKGROUND_INTERVAL = 20*1000; 916 917 // The amount of time until PSS when a process first becomes cached. 918 private static final int PSS_FIRST_CACHED_INTERVAL = 20*1000; 919 920 // The amount of time until PSS when an important process stays in the same state. 921 private static final int PSS_SAME_PERSISTENT_INTERVAL = 10*60*1000; 922 923 // The amount of time until PSS when the top process stays in the same state. 924 private static final int PSS_SAME_TOP_INTERVAL = 1*60*1000; 925 926 // The amount of time until PSS when an important process stays in the same state. 927 private static final int PSS_SAME_IMPORTANT_INTERVAL = 10*60*1000; 928 929 // The amount of time until PSS when a service process stays in the same state. 930 private static final int PSS_SAME_SERVICE_INTERVAL = 5*60*1000; 931 932 // The amount of time until PSS when a cached process stays in the same state. 933 private static final int PSS_SAME_CACHED_INTERVAL = 10*60*1000; 934 935 // The amount of time until PSS when a persistent process first appears. 936 private static final int PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL = 1*60*1000; 937 938 // The amount of time until PSS when a process first becomes top. 939 private static final int PSS_FIRST_ASLEEP_TOP_INTERVAL = 20*1000; 940 941 // The amount of time until PSS when a process first goes into the background. 942 private static final int PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL = 30*1000; 943 944 // The amount of time until PSS when a process first becomes cached. 945 private static final int PSS_FIRST_ASLEEP_CACHED_INTERVAL = 1*60*1000; 946 947 // The minimum time interval after a state change it is safe to collect PSS. 948 public static final int PSS_TEST_MIN_TIME_FROM_STATE_CHANGE = 10*1000; 949 950 // The amount of time during testing until PSS when a process first becomes top. 951 private static final int PSS_TEST_FIRST_TOP_INTERVAL = 3*1000; 952 953 // The amount of time during testing until PSS when a process first goes into the background. 954 private static final int PSS_TEST_FIRST_BACKGROUND_INTERVAL = 5*1000; 955 956 // The amount of time during testing until PSS when an important process stays in same state. 957 private static final int PSS_TEST_SAME_IMPORTANT_INTERVAL = 10*1000; 958 959 // The amount of time during testing until PSS when a background process stays in same state. 960 private static final int PSS_TEST_SAME_BACKGROUND_INTERVAL = 15*1000; 961 962 public static final int PROC_MEM_PERSISTENT = 0; 963 public static final int PROC_MEM_TOP = 1; 964 public static final int PROC_MEM_IMPORTANT = 2; 965 public static final int PROC_MEM_SERVICE = 3; 966 public static final int PROC_MEM_CACHED = 4; 967 public static final int PROC_MEM_NUM = 5; 968 969 // Map large set of system process states to 970 private static final int[] sProcStateToProcMem = new int[] { 971 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT 972 PROC_MEM_PERSISTENT, // ActivityManager.PROCESS_STATE_PERSISTENT_UI 973 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP 974 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE_LOCATION 975 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE 976 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_BOUND_TOP 977 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE 978 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND 979 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND 980 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_TRANSIENT_BACKGROUND 981 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_BACKUP 982 PROC_MEM_SERVICE, // ActivityManager.PROCESS_STATE_SERVICE 983 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_RECEIVER 984 PROC_MEM_TOP, // ActivityManager.PROCESS_STATE_TOP_SLEEPING 985 PROC_MEM_IMPORTANT, // ActivityManager.PROCESS_STATE_HEAVY_WEIGHT 986 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_HOME 987 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_LAST_ACTIVITY 988 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY 989 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT 990 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_RECENT 991 PROC_MEM_CACHED, // ActivityManager.PROCESS_STATE_CACHED_EMPTY 992 }; 993 994 private static final long[] sFirstAwakePssTimes = new long[] { 995 PSS_FIRST_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT 996 PSS_FIRST_TOP_INTERVAL, // PROC_MEM_TOP 997 PSS_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT 998 PSS_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE 999 PSS_FIRST_CACHED_INTERVAL, // PROC_MEM_CACHED 1000 }; 1001 1002 private static final long[] sSameAwakePssTimes = new long[] { 1003 PSS_SAME_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT 1004 PSS_SAME_TOP_INTERVAL, // PROC_MEM_TOP 1005 PSS_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT 1006 PSS_SAME_SERVICE_INTERVAL, // PROC_MEM_SERVICE 1007 PSS_SAME_CACHED_INTERVAL, // PROC_MEM_CACHED 1008 }; 1009 1010 private static final long[] sFirstAsleepPssTimes = new long[] { 1011 PSS_FIRST_ASLEEP_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT 1012 PSS_FIRST_ASLEEP_TOP_INTERVAL, // PROC_MEM_TOP 1013 PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT 1014 PSS_FIRST_ASLEEP_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE 1015 PSS_FIRST_ASLEEP_CACHED_INTERVAL, // PROC_MEM_CACHED 1016 }; 1017 1018 private static final long[] sSameAsleepPssTimes = new long[] { 1019 PSS_SAME_PERSISTENT_INTERVAL, // PROC_MEM_PERSISTENT 1020 PSS_SAME_TOP_INTERVAL, // PROC_MEM_TOP 1021 PSS_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT 1022 PSS_SAME_SERVICE_INTERVAL, // PROC_MEM_SERVICE 1023 PSS_SAME_CACHED_INTERVAL, // PROC_MEM_CACHED 1024 }; 1025 1026 private static final long[] sTestFirstPssTimes = new long[] { 1027 PSS_TEST_FIRST_TOP_INTERVAL, // PROC_MEM_PERSISTENT 1028 PSS_TEST_FIRST_TOP_INTERVAL, // PROC_MEM_TOP 1029 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_IMPORTANT 1030 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE 1031 PSS_TEST_FIRST_BACKGROUND_INTERVAL, // PROC_MEM_CACHED 1032 }; 1033 1034 private static final long[] sTestSamePssTimes = new long[] { 1035 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_PERSISTENT 1036 PSS_TEST_SAME_IMPORTANT_INTERVAL, // PROC_MEM_TOP 1037 PSS_TEST_SAME_IMPORTANT_INTERVAL, // PROC_MEM_IMPORTANT 1038 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_SERVICE 1039 PSS_TEST_SAME_BACKGROUND_INTERVAL, // PROC_MEM_CACHED 1040 }; 1041 1042 public static final class ProcStateMemTracker { 1043 final int[] mHighestMem = new int[PROC_MEM_NUM]; 1044 final float[] mScalingFactor = new float[PROC_MEM_NUM]; 1045 int mTotalHighestMem = PROC_MEM_CACHED; 1046 1047 int mPendingMemState; 1048 int mPendingHighestMemState; 1049 float mPendingScalingFactor; 1050 1051 public ProcStateMemTracker() { 1052 for (int i = PROC_MEM_PERSISTENT; i < PROC_MEM_NUM; i++) { 1053 mHighestMem[i] = PROC_MEM_NUM; 1054 mScalingFactor[i] = 1.0f; 1055 } 1056 mPendingMemState = -1; 1057 } 1058 1059 public void dumpLine(PrintWriter pw) { 1060 pw.print("best="); 1061 pw.print(mTotalHighestMem); 1062 pw.print(" ("); 1063 boolean needSep = false; 1064 for (int i = 0; i < PROC_MEM_NUM; i++) { 1065 if (mHighestMem[i] < PROC_MEM_NUM) { 1066 if (needSep) { 1067 pw.print(", "); 1068 needSep = false; 1069 } 1070 pw.print(i); 1071 pw.print("="); 1072 pw.print(mHighestMem[i]); 1073 pw.print(" "); 1074 pw.print(mScalingFactor[i]); 1075 pw.print("x"); 1076 needSep = true; 1077 } 1078 } 1079 pw.print(")"); 1080 if (mPendingMemState >= 0) { 1081 pw.print(" / pending state="); 1082 pw.print(mPendingMemState); 1083 pw.print(" highest="); 1084 pw.print(mPendingHighestMemState); 1085 pw.print(" "); 1086 pw.print(mPendingScalingFactor); 1087 pw.print("x"); 1088 } 1089 pw.println(); 1090 } 1091 } 1092 1093 public static boolean procStatesDifferForMem(int procState1, int procState2) { 1094 return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2]; 1095 } 1096 1097 public static long minTimeFromStateChange(boolean test) { 1098 return test ? PSS_TEST_MIN_TIME_FROM_STATE_CHANGE : PSS_MIN_TIME_FROM_STATE_CHANGE; 1099 } 1100 1101 public static void commitNextPssTime(ProcStateMemTracker tracker) { 1102 if (tracker.mPendingMemState >= 0) { 1103 tracker.mHighestMem[tracker.mPendingMemState] = tracker.mPendingHighestMemState; 1104 tracker.mScalingFactor[tracker.mPendingMemState] = tracker.mPendingScalingFactor; 1105 tracker.mTotalHighestMem = tracker.mPendingHighestMemState; 1106 tracker.mPendingMemState = -1; 1107 } 1108 } 1109 1110 public static void abortNextPssTime(ProcStateMemTracker tracker) { 1111 tracker.mPendingMemState = -1; 1112 } 1113 1114 public static long computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test, 1115 boolean sleeping, long now) { 1116 boolean first; 1117 float scalingFactor; 1118 final int memState = sProcStateToProcMem[procState]; 1119 if (tracker != null) { 1120 final int highestMemState = memState < tracker.mTotalHighestMem 1121 ? memState : tracker.mTotalHighestMem; 1122 first = highestMemState < tracker.mHighestMem[memState]; 1123 tracker.mPendingMemState = memState; 1124 tracker.mPendingHighestMemState = highestMemState; 1125 if (first) { 1126 tracker.mPendingScalingFactor = scalingFactor = 1.0f; 1127 } else { 1128 scalingFactor = tracker.mScalingFactor[memState]; 1129 tracker.mPendingScalingFactor = scalingFactor * 1.5f; 1130 } 1131 } else { 1132 first = true; 1133 scalingFactor = 1.0f; 1134 } 1135 final long[] table = test 1136 ? (first 1137 ? sTestFirstPssTimes 1138 : sTestSamePssTimes) 1139 : (first 1140 ? (sleeping ? sFirstAsleepPssTimes : sFirstAwakePssTimes) 1141 : (sleeping ? sSameAsleepPssTimes : sSameAwakePssTimes)); 1142 long delay = (long)(table[memState] * scalingFactor); 1143 if (delay > PSS_MAX_INTERVAL) { 1144 delay = PSS_MAX_INTERVAL; 1145 } 1146 return now + delay; 1147 } 1148 1149 long getMemLevel(int adjustment) { 1150 for (int i = 0; i < mOomAdj.length; i++) { 1151 if (adjustment <= mOomAdj[i]) { 1152 return mOomMinFree[i] * 1024; 1153 } 1154 } 1155 return mOomMinFree[mOomAdj.length - 1] * 1024; 1156 } 1157 1158 /** 1159 * Return the maximum pss size in kb that we consider a process acceptable to 1160 * restore from its cached state for running in the background when RAM is low. 1161 */ 1162 long getCachedRestoreThresholdKb() { 1163 return mCachedRestoreLevel; 1164 } 1165 1166 /** 1167 * Set the out-of-memory badness adjustment for a process. 1168 * If {@code pid <= 0}, this method will be a no-op. 1169 * 1170 * @param pid The process identifier to set. 1171 * @param uid The uid of the app 1172 * @param amt Adjustment value -- lmkd allows -1000 to +1000 1173 * 1174 * {@hide} 1175 */ 1176 public static void setOomAdj(int pid, int uid, int amt) { 1177 // This indicates that the process is not started yet and so no need to proceed further. 1178 if (pid <= 0) { 1179 return; 1180 } 1181 if (amt == UNKNOWN_ADJ) 1182 return; 1183 1184 long start = SystemClock.elapsedRealtime(); 1185 ByteBuffer buf = ByteBuffer.allocate(4 * 4); 1186 buf.putInt(LMK_PROCPRIO); 1187 buf.putInt(pid); 1188 buf.putInt(uid); 1189 buf.putInt(amt); 1190 writeLmkd(buf, null); 1191 long now = SystemClock.elapsedRealtime(); 1192 if ((now-start) > 250) { 1193 Slog.w("ActivityManager", "SLOW OOM ADJ: " + (now-start) + "ms for pid " + pid 1194 + " = " + amt); 1195 } 1196 } 1197 1198 /* 1199 * {@hide} 1200 */ 1201 public static final void remove(int pid) { 1202 // This indicates that the process is not started yet and so no need to proceed further. 1203 if (pid <= 0) { 1204 return; 1205 } 1206 ByteBuffer buf = ByteBuffer.allocate(4 * 2); 1207 buf.putInt(LMK_PROCREMOVE); 1208 buf.putInt(pid); 1209 writeLmkd(buf, null); 1210 } 1211 1212 /* 1213 * {@hide} 1214 */ 1215 public static final Integer getLmkdKillCount(int min_oom_adj, int max_oom_adj) { 1216 ByteBuffer buf = ByteBuffer.allocate(4 * 3); 1217 ByteBuffer repl = ByteBuffer.allocate(4 * 2); 1218 buf.putInt(LMK_GETKILLCNT); 1219 buf.putInt(min_oom_adj); 1220 buf.putInt(max_oom_adj); 1221 if (writeLmkd(buf, repl)) { 1222 int i = repl.getInt(); 1223 if (i != LMK_GETKILLCNT) { 1224 Slog.e("ActivityManager", "Failed to get kill count, code mismatch"); 1225 return null; 1226 } 1227 return new Integer(repl.getInt()); 1228 } 1229 return null; 1230 } 1231 1232 @GuardedBy("sLmkdSocketLock") 1233 private static boolean openLmkdSocketLS() { 1234 try { 1235 sLmkdSocket = new LocalSocket(LocalSocket.SOCKET_SEQPACKET); 1236 sLmkdSocket.connect( 1237 new LocalSocketAddress("lmkd", 1238 LocalSocketAddress.Namespace.RESERVED)); 1239 sLmkdOutputStream = sLmkdSocket.getOutputStream(); 1240 sLmkdInputStream = sLmkdSocket.getInputStream(); 1241 } catch (IOException ex) { 1242 Slog.w(TAG, "lowmemorykiller daemon socket open failed"); 1243 sLmkdSocket = null; 1244 return false; 1245 } 1246 1247 return true; 1248 } 1249 1250 // Never call directly, use writeLmkd() instead 1251 @GuardedBy("sLmkdSocketLock") 1252 private static boolean writeLmkdCommandLS(ByteBuffer buf) { 1253 try { 1254 sLmkdOutputStream.write(buf.array(), 0, buf.position()); 1255 } catch (IOException ex) { 1256 Slog.w(TAG, "Error writing to lowmemorykiller socket"); 1257 IoUtils.closeQuietly(sLmkdSocket); 1258 sLmkdSocket = null; 1259 return false; 1260 } 1261 return true; 1262 } 1263 1264 // Never call directly, use writeLmkd() instead 1265 @GuardedBy("sLmkdSocketLock") 1266 private static boolean readLmkdReplyLS(ByteBuffer buf) { 1267 int len; 1268 try { 1269 len = sLmkdInputStream.read(buf.array(), 0, buf.array().length); 1270 if (len == buf.array().length) { 1271 return true; 1272 } 1273 } catch (IOException ex) { 1274 Slog.w(TAG, "Error reading from lowmemorykiller socket"); 1275 } 1276 1277 IoUtils.closeQuietly(sLmkdSocket); 1278 sLmkdSocket = null; 1279 return false; 1280 } 1281 1282 private static boolean writeLmkd(ByteBuffer buf, ByteBuffer repl) { 1283 synchronized (sLmkdSocketLock) { 1284 for (int i = 0; i < 3; i++) { 1285 if (sLmkdSocket == null) { 1286 if (openLmkdSocketLS() == false) { 1287 try { 1288 Thread.sleep(1000); 1289 } catch (InterruptedException ie) { 1290 } 1291 continue; 1292 } 1293 1294 // Purge any previously registered pids 1295 ByteBuffer purge_buf = ByteBuffer.allocate(4); 1296 purge_buf.putInt(LMK_PROCPURGE); 1297 if (writeLmkdCommandLS(purge_buf) == false) { 1298 // Write failed, skip the rest and retry 1299 continue; 1300 } 1301 } 1302 if (writeLmkdCommandLS(buf) && (repl == null || readLmkdReplyLS(repl))) { 1303 return true; 1304 } 1305 } 1306 } 1307 return false; 1308 } 1309 1310 static void killProcessGroup(int uid, int pid) { 1311 /* static; one-time init here */ 1312 if (sKillHandler != null) { 1313 sKillHandler.sendMessage( 1314 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid)); 1315 } else { 1316 Slog.w(TAG, "Asked to kill process group before system bringup!"); 1317 Process.killProcessGroup(uid, pid); 1318 } 1319 } 1320 1321 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean 1322 keepIfLarge) { 1323 if (uid == SYSTEM_UID) { 1324 // The system gets to run in any process. If there are multiple 1325 // processes with the same uid, just pick the first (this 1326 // should never happen). 1327 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName); 1328 if (procs == null) return null; 1329 final int procCount = procs.size(); 1330 for (int i = 0; i < procCount; i++) { 1331 final int procUid = procs.keyAt(i); 1332 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) { 1333 // Don't use an app process or different user process for system component. 1334 continue; 1335 } 1336 return procs.valueAt(i); 1337 } 1338 } 1339 ProcessRecord proc = mProcessNames.get(processName, uid); 1340 if (false && proc != null && !keepIfLarge 1341 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY 1342 && proc.lastCachedPss >= 4000) { 1343 // Turn this condition on to cause killing to happen regularly, for testing. 1344 if (proc.baseProcessTracker != null) { 1345 proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList, proc.lastCachedPss); 1346 for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) { 1347 ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg); 1348 StatsLog.write(StatsLog.CACHED_KILL_REPORTED, 1349 proc.info.uid, 1350 holder.state.getName(), 1351 holder.state.getPackage(), 1352 proc.lastCachedPss, holder.appVersion); 1353 } 1354 } 1355 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 1356 } else if (proc != null && !keepIfLarge 1357 && mService.mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL 1358 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) { 1359 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc 1360 .lastCachedPss); 1361 if (proc.lastCachedPss >= getCachedRestoreThresholdKb()) { 1362 if (proc.baseProcessTracker != null) { 1363 proc.baseProcessTracker.reportCachedKill(proc.pkgList.mPkgList, 1364 proc.lastCachedPss); 1365 for (int ipkg = proc.pkgList.size() - 1; ipkg >= 0; ipkg--) { 1366 ProcessStats.ProcessStateHolder holder = proc.pkgList.valueAt(ipkg); 1367 StatsLog.write(StatsLog.CACHED_KILL_REPORTED, 1368 proc.info.uid, 1369 holder.state.getName(), 1370 holder.state.getPackage(), 1371 proc.lastCachedPss, holder.appVersion); 1372 } 1373 } 1374 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true); 1375 } 1376 } 1377 return proc; 1378 } 1379 1380 void getMemoryInfo(ActivityManager.MemoryInfo outInfo) { 1381 final long homeAppMem = getMemLevel(HOME_APP_ADJ); 1382 final long cachedAppMem = getMemLevel(CACHED_APP_MIN_ADJ); 1383 outInfo.availMem = getFreeMemory(); 1384 outInfo.totalMem = getTotalMemory(); 1385 outInfo.threshold = homeAppMem; 1386 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2)); 1387 outInfo.hiddenAppThreshold = cachedAppMem; 1388 outInfo.secondaryServerThreshold = getMemLevel(SERVICE_ADJ); 1389 outInfo.visibleAppThreshold = getMemLevel(VISIBLE_APP_ADJ); 1390 outInfo.foregroundAppThreshold = getMemLevel(FOREGROUND_APP_ADJ); 1391 } 1392 1393 ProcessRecord findAppProcessLocked(IBinder app, String reason) { 1394 final int NP = mProcessNames.getMap().size(); 1395 for (int ip = 0; ip < NP; ip++) { 1396 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 1397 final int NA = apps.size(); 1398 for (int ia = 0; ia < NA; ia++) { 1399 ProcessRecord p = apps.valueAt(ia); 1400 if (p.thread != null && p.thread.asBinder() == app) { 1401 return p; 1402 } 1403 } 1404 } 1405 1406 Slog.w(TAG, "Can't find mystery application for " + reason 1407 + " from pid=" + Binder.getCallingPid() 1408 + " uid=" + Binder.getCallingUid() + ": " + app); 1409 return null; 1410 } 1411 1412 private void checkSlow(long startTime, String where) { 1413 long now = SystemClock.uptimeMillis(); 1414 if ((now - startTime) > 50) { 1415 // If we are taking more than 50ms, log about it. 1416 Slog.w(TAG, "Slow operation: " + (now - startTime) + "ms so far, now at " + where); 1417 } 1418 } 1419 1420 /** 1421 * @return {@code true} if process start is successful, false otherwise. 1422 * @param app 1423 * @param hostingRecord 1424 * @param disableHiddenApiChecks 1425 * @param abiOverride 1426 */ 1427 @GuardedBy("mService") 1428 boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord, 1429 boolean disableHiddenApiChecks, boolean mountExtStorageFull, 1430 String abiOverride) { 1431 if (app.pendingStart) { 1432 return true; 1433 } 1434 long startTime = SystemClock.elapsedRealtime(); 1435 if (app.pid > 0 && app.pid != ActivityManagerService.MY_PID) { 1436 checkSlow(startTime, "startProcess: removing from pids map"); 1437 mService.mPidsSelfLocked.remove(app); 1438 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 1439 checkSlow(startTime, "startProcess: done removing from pids map"); 1440 app.setPid(0); 1441 app.startSeq = 0; 1442 } 1443 1444 if (DEBUG_PROCESSES && mService.mProcessesOnHold.contains(app)) Slog.v( 1445 TAG_PROCESSES, 1446 "startProcessLocked removing on hold: " + app); 1447 mService.mProcessesOnHold.remove(app); 1448 1449 checkSlow(startTime, "startProcess: starting to update cpu stats"); 1450 mService.updateCpuStats(); 1451 checkSlow(startTime, "startProcess: done updating cpu stats"); 1452 1453 try { 1454 try { 1455 final int userId = UserHandle.getUserId(app.uid); 1456 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId); 1457 } catch (RemoteException e) { 1458 throw e.rethrowAsRuntimeException(); 1459 } 1460 1461 int uid = app.uid; 1462 int[] gids = null; 1463 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE; 1464 if (!app.isolated) { 1465 int[] permGids = null; 1466 try { 1467 checkSlow(startTime, "startProcess: getting gids from package manager"); 1468 final IPackageManager pm = AppGlobals.getPackageManager(); 1469 permGids = pm.getPackageGids(app.info.packageName, 1470 MATCH_DIRECT_BOOT_AUTO, app.userId); 1471 if (StorageManager.hasIsolatedStorage() && mountExtStorageFull) { 1472 mountExternal = Zygote.MOUNT_EXTERNAL_FULL; 1473 } else { 1474 StorageManagerInternal storageManagerInternal = LocalServices.getService( 1475 StorageManagerInternal.class); 1476 mountExternal = storageManagerInternal.getExternalStorageMountMode(uid, 1477 app.info.packageName); 1478 } 1479 } catch (RemoteException e) { 1480 throw e.rethrowAsRuntimeException(); 1481 } 1482 1483 /* 1484 * Add shared application and profile GIDs so applications can share some 1485 * resources like shared libraries and access user-wide resources 1486 */ 1487 if (ArrayUtils.isEmpty(permGids)) { 1488 gids = new int[3]; 1489 } else { 1490 gids = new int[permGids.length + 3]; 1491 System.arraycopy(permGids, 0, gids, 3, permGids.length); 1492 } 1493 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid)); 1494 gids[1] = UserHandle.getCacheAppGid(UserHandle.getAppId(uid)); 1495 gids[2] = UserHandle.getUserGid(UserHandle.getUserId(uid)); 1496 1497 // Replace any invalid GIDs 1498 if (gids[0] == UserHandle.ERR_GID) gids[0] = gids[2]; 1499 if (gids[1] == UserHandle.ERR_GID) gids[1] = gids[2]; 1500 } 1501 app.mountMode = mountExternal; 1502 checkSlow(startTime, "startProcess: building args"); 1503 if (mService.mAtmInternal.isFactoryTestProcess(app.getWindowProcessController())) { 1504 uid = 0; 1505 } 1506 int runtimeFlags = 0; 1507 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 1508 runtimeFlags |= Zygote.DEBUG_ENABLE_JDWP; 1509 runtimeFlags |= Zygote.DEBUG_JAVA_DEBUGGABLE; 1510 // Also turn on CheckJNI for debuggable apps. It's quite 1511 // awkward to turn on otherwise. 1512 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1513 1514 // Check if the developer does not want ART verification 1515 if (android.provider.Settings.Global.getInt(mService.mContext.getContentResolver(), 1516 android.provider.Settings.Global.ART_VERIFIER_VERIFY_DEBUGGABLE, 1) == 0) { 1517 runtimeFlags |= Zygote.DISABLE_VERIFIER; 1518 Slog.w(TAG_PROCESSES, app + ": ART verification disabled"); 1519 } 1520 } 1521 // Run the app in safe mode if its manifest requests so or the 1522 // system is booted in safe mode. 1523 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 || 1524 mService.mSafeMode == true) { 1525 runtimeFlags |= Zygote.DEBUG_ENABLE_SAFEMODE; 1526 } 1527 if ((app.info.privateFlags & ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL) != 0) { 1528 runtimeFlags |= Zygote.PROFILE_FROM_SHELL; 1529 } 1530 if ("1".equals(SystemProperties.get("debug.checkjni"))) { 1531 runtimeFlags |= Zygote.DEBUG_ENABLE_CHECKJNI; 1532 } 1533 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info"); 1534 if ("1".equals(genDebugInfoProperty) || "true".equals(genDebugInfoProperty)) { 1535 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; 1536 } 1537 String genMiniDebugInfoProperty = SystemProperties.get("dalvik.vm.minidebuginfo"); 1538 if ("1".equals(genMiniDebugInfoProperty) || "true".equals(genMiniDebugInfoProperty)) { 1539 runtimeFlags |= Zygote.DEBUG_GENERATE_MINI_DEBUG_INFO; 1540 } 1541 if ("1".equals(SystemProperties.get("debug.jni.logging"))) { 1542 runtimeFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING; 1543 } 1544 if ("1".equals(SystemProperties.get("debug.assert"))) { 1545 runtimeFlags |= Zygote.DEBUG_ENABLE_ASSERT; 1546 } 1547 if (mService.mNativeDebuggingApp != null 1548 && mService.mNativeDebuggingApp.equals(app.processName)) { 1549 // Enable all debug flags required by the native debugger. 1550 runtimeFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything 1551 runtimeFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info 1552 runtimeFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations 1553 mService.mNativeDebuggingApp = null; 1554 } 1555 1556 if (app.info.isEmbeddedDexUsed() 1557 || (app.info.isPrivilegedApp() 1558 && DexManager.isPackageSelectedToRunOob(app.pkgList.mPkgList.keySet()))) { 1559 runtimeFlags |= Zygote.ONLY_USE_SYSTEM_OAT_FILES; 1560 } 1561 1562 if (!disableHiddenApiChecks && !mService.mHiddenApiBlacklist.isDisabled()) { 1563 app.info.maybeUpdateHiddenApiEnforcementPolicy( 1564 mService.mHiddenApiBlacklist.getPolicy()); 1565 @ApplicationInfo.HiddenApiEnforcementPolicy int policy = 1566 app.info.getHiddenApiEnforcementPolicy(); 1567 int policyBits = (policy << Zygote.API_ENFORCEMENT_POLICY_SHIFT); 1568 if ((policyBits & Zygote.API_ENFORCEMENT_POLICY_MASK) != policyBits) { 1569 throw new IllegalStateException("Invalid API policy: " + policy); 1570 } 1571 runtimeFlags |= policyBits; 1572 } 1573 1574 String useAppImageCache = SystemProperties.get( 1575 PROPERTY_USE_APP_IMAGE_STARTUP_CACHE, ""); 1576 // Property defaults to true currently. 1577 if (!TextUtils.isEmpty(useAppImageCache) && !useAppImageCache.equals("false")) { 1578 runtimeFlags |= Zygote.USE_APP_IMAGE_STARTUP_CACHE; 1579 } 1580 1581 String invokeWith = null; 1582 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) { 1583 // Debuggable apps may include a wrapper script with their library directory. 1584 String wrapperFileName = app.info.nativeLibraryDir + "/wrap.sh"; 1585 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 1586 try { 1587 if (new File(wrapperFileName).exists()) { 1588 invokeWith = "/system/bin/logwrapper " + wrapperFileName; 1589 } 1590 } finally { 1591 StrictMode.setThreadPolicy(oldPolicy); 1592 } 1593 } 1594 1595 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi; 1596 if (requiredAbi == null) { 1597 requiredAbi = Build.SUPPORTED_ABIS[0]; 1598 } 1599 1600 String instructionSet = null; 1601 if (app.info.primaryCpuAbi != null) { 1602 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi); 1603 } 1604 1605 app.gids = gids; 1606 app.setRequiredAbi(requiredAbi); 1607 app.instructionSet = instructionSet; 1608 1609 // the per-user SELinux context must be set 1610 if (TextUtils.isEmpty(app.info.seInfoUser)) { 1611 Slog.wtf(ActivityManagerService.TAG, "SELinux tag not defined", 1612 new IllegalStateException("SELinux tag not defined for " 1613 + app.info.packageName + " (uid " + app.uid + ")")); 1614 } 1615 final String seInfo = app.info.seInfo 1616 + (TextUtils.isEmpty(app.info.seInfoUser) ? "" : app.info.seInfoUser); 1617 // Start the process. It will either succeed and return a result containing 1618 // the PID of the new process, or else throw a RuntimeException. 1619 final String entryPoint = "android.app.ActivityThread"; 1620 1621 return startProcessLocked(hostingRecord, entryPoint, app, uid, gids, 1622 runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, invokeWith, 1623 startTime); 1624 } catch (RuntimeException e) { 1625 Slog.e(ActivityManagerService.TAG, "Failure starting process " + app.processName, e); 1626 1627 // Something went very wrong while trying to start this process; one 1628 // common case is when the package is frozen due to an active 1629 // upgrade. To recover, clean up any active bookkeeping related to 1630 // starting this process. (We already invoked this method once when 1631 // the package was initially frozen through KILL_APPLICATION_MSG, so 1632 // it doesn't hurt to use it again.) 1633 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), 1634 false, false, true, false, false, app.userId, "start failure"); 1635 return false; 1636 } 1637 } 1638 1639 @GuardedBy("mService") 1640 boolean startProcessLocked(HostingRecord hostingRecord, 1641 String entryPoint, 1642 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal, 1643 String seInfo, String requiredAbi, String instructionSet, String invokeWith, 1644 long startTime) { 1645 app.pendingStart = true; 1646 app.killedByAm = false; 1647 app.removed = false; 1648 app.killed = false; 1649 if (app.startSeq != 0) { 1650 Slog.wtf(TAG, "startProcessLocked processName:" + app.processName 1651 + " with non-zero startSeq:" + app.startSeq); 1652 } 1653 if (app.pid != 0) { 1654 Slog.wtf(TAG, "startProcessLocked processName:" + app.processName 1655 + " with non-zero pid:" + app.pid); 1656 } 1657 final long startSeq = app.startSeq = ++mProcStartSeqCounter; 1658 app.setStartParams(uid, hostingRecord, seInfo, startTime); 1659 app.setUsingWrapper(invokeWith != null 1660 || SystemProperties.get("wrap." + app.processName) != null); 1661 mPendingStarts.put(startSeq, app); 1662 1663 if (mService.mConstants.FLAG_PROCESS_START_ASYNC) { 1664 if (DEBUG_PROCESSES) Slog.i(TAG_PROCESSES, 1665 "Posting procStart msg for " + app.toShortString()); 1666 mService.mProcStartHandler.post(() -> { 1667 try { 1668 final Process.ProcessStartResult startResult = startProcess(app.hostingRecord, 1669 entryPoint, app, app.startUid, gids, runtimeFlags, mountExternal, 1670 app.seInfo, requiredAbi, instructionSet, invokeWith, app.startTime); 1671 synchronized (mService) { 1672 handleProcessStartedLocked(app, startResult, startSeq); 1673 } 1674 } catch (RuntimeException e) { 1675 synchronized (mService) { 1676 Slog.e(ActivityManagerService.TAG, "Failure starting process " 1677 + app.processName, e); 1678 mPendingStarts.remove(startSeq); 1679 app.pendingStart = false; 1680 mService.forceStopPackageLocked(app.info.packageName, 1681 UserHandle.getAppId(app.uid), 1682 false, false, true, false, false, app.userId, "start failure"); 1683 } 1684 } 1685 }); 1686 return true; 1687 } else { 1688 try { 1689 final Process.ProcessStartResult startResult = startProcess(hostingRecord, 1690 entryPoint, app, 1691 uid, gids, runtimeFlags, mountExternal, seInfo, requiredAbi, instructionSet, 1692 invokeWith, startTime); 1693 handleProcessStartedLocked(app, startResult.pid, startResult.usingWrapper, 1694 startSeq, false); 1695 } catch (RuntimeException e) { 1696 Slog.e(ActivityManagerService.TAG, "Failure starting process " 1697 + app.processName, e); 1698 app.pendingStart = false; 1699 mService.forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), 1700 false, false, true, false, false, app.userId, "start failure"); 1701 } 1702 return app.pid > 0; 1703 } 1704 } 1705 1706 @GuardedBy("mService") 1707 public void killAppZygoteIfNeededLocked(AppZygote appZygote) { 1708 final ApplicationInfo appInfo = appZygote.getAppInfo(); 1709 ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote); 1710 if (zygoteProcesses != null && zygoteProcesses.size() == 0) { 1711 // Only remove if no longer in use now 1712 mAppZygotes.remove(appInfo.processName, appInfo.uid); 1713 mAppZygoteProcesses.remove(appZygote); 1714 mAppIsolatedUidRangeAllocator.freeUidRangeLocked(appInfo); 1715 appZygote.stopZygote(); 1716 } 1717 } 1718 1719 @GuardedBy("mService") 1720 private void removeProcessFromAppZygoteLocked(final ProcessRecord app) { 1721 // Free the isolated uid for this process 1722 final IsolatedUidRange appUidRange = 1723 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked(app.info.processName, 1724 app.hostingRecord.getDefiningUid()); 1725 if (appUidRange != null) { 1726 appUidRange.freeIsolatedUidLocked(app.uid); 1727 } 1728 1729 final AppZygote appZygote = mAppZygotes.get(app.info.processName, 1730 app.hostingRecord.getDefiningUid()); 1731 if (appZygote != null) { 1732 ArrayList<ProcessRecord> zygoteProcesses = mAppZygoteProcesses.get(appZygote); 1733 zygoteProcesses.remove(app); 1734 if (zygoteProcesses.size() == 0) { 1735 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG); 1736 if (app.removed) { 1737 // If we stopped this process because the package hosting it was removed, 1738 // there's no point in delaying the app zygote kill. 1739 killAppZygoteIfNeededLocked(appZygote); 1740 } else { 1741 Message msg = mService.mHandler.obtainMessage(KILL_APP_ZYGOTE_MSG); 1742 msg.obj = appZygote; 1743 mService.mHandler.sendMessageDelayed(msg, KILL_APP_ZYGOTE_DELAY_MS); 1744 } 1745 } 1746 } 1747 } 1748 1749 private AppZygote createAppZygoteForProcessIfNeeded(final ProcessRecord app) { 1750 synchronized (mService) { 1751 // The UID for the app zygote should be the UID of the application hosting 1752 // the service. 1753 final int uid = app.hostingRecord.getDefiningUid(); 1754 AppZygote appZygote = mAppZygotes.get(app.info.processName, uid); 1755 final ArrayList<ProcessRecord> zygoteProcessList; 1756 if (appZygote == null) { 1757 if (DEBUG_PROCESSES) { 1758 Slog.d(TAG_PROCESSES, "Creating new app zygote."); 1759 } 1760 final IsolatedUidRange uidRange = 1761 mAppIsolatedUidRangeAllocator.getIsolatedUidRangeLocked( 1762 app.info.processName, app.hostingRecord.getDefiningUid()); 1763 final int userId = UserHandle.getUserId(uid); 1764 // Create the app-zygote and provide it with the UID-range it's allowed 1765 // to setresuid/setresgid to. 1766 final int firstUid = UserHandle.getUid(userId, uidRange.mFirstUid); 1767 final int lastUid = UserHandle.getUid(userId, uidRange.mLastUid); 1768 ApplicationInfo appInfo = new ApplicationInfo(app.info); 1769 // If this was an external service, the package name and uid in the passed in 1770 // ApplicationInfo have been changed to match those of the calling package; 1771 // that is not what we want for the AppZygote though, which needs to have the 1772 // packageName and uid of the defining application. This is because the 1773 // preloading only makes sense in the context of the defining application, 1774 // not the calling one. 1775 appInfo.packageName = app.hostingRecord.getDefiningPackageName(); 1776 appInfo.uid = uid; 1777 appZygote = new AppZygote(appInfo, uid, firstUid, lastUid); 1778 mAppZygotes.put(app.info.processName, uid, appZygote); 1779 zygoteProcessList = new ArrayList<ProcessRecord>(); 1780 mAppZygoteProcesses.put(appZygote, zygoteProcessList); 1781 } else { 1782 if (DEBUG_PROCESSES) { 1783 Slog.d(TAG_PROCESSES, "Reusing existing app zygote."); 1784 } 1785 mService.mHandler.removeMessages(KILL_APP_ZYGOTE_MSG, appZygote); 1786 zygoteProcessList = mAppZygoteProcesses.get(appZygote); 1787 } 1788 // Note that we already add the app to mAppZygoteProcesses here; 1789 // this is so that another thread can't come in and kill the zygote 1790 // before we've even tried to start the process. If the process launch 1791 // goes wrong, we'll clean this up in removeProcessNameLocked() 1792 zygoteProcessList.add(app); 1793 1794 return appZygote; 1795 } 1796 } 1797 1798 private Process.ProcessStartResult startProcess(HostingRecord hostingRecord, String entryPoint, 1799 ProcessRecord app, int uid, int[] gids, int runtimeFlags, int mountExternal, 1800 String seInfo, String requiredAbi, String instructionSet, String invokeWith, 1801 long startTime) { 1802 try { 1803 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " + 1804 app.processName); 1805 checkSlow(startTime, "startProcess: asking zygote to start proc"); 1806 final Process.ProcessStartResult startResult; 1807 if (hostingRecord.usesWebviewZygote()) { 1808 startResult = startWebView(entryPoint, 1809 app.processName, uid, uid, gids, runtimeFlags, mountExternal, 1810 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 1811 app.info.dataDir, null, app.info.packageName, 1812 new String[] {PROC_START_SEQ_IDENT + app.startSeq}); 1813 } else if (hostingRecord.usesAppZygote()) { 1814 final AppZygote appZygote = createAppZygoteForProcessIfNeeded(app); 1815 1816 startResult = appZygote.getProcess().start(entryPoint, 1817 app.processName, uid, uid, gids, runtimeFlags, mountExternal, 1818 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 1819 app.info.dataDir, null, app.info.packageName, 1820 /*useUsapPool=*/ false, 1821 new String[] {PROC_START_SEQ_IDENT + app.startSeq}); 1822 } else { 1823 startResult = Process.start(entryPoint, 1824 app.processName, uid, uid, gids, runtimeFlags, mountExternal, 1825 app.info.targetSdkVersion, seInfo, requiredAbi, instructionSet, 1826 app.info.dataDir, invokeWith, app.info.packageName, 1827 new String[] {PROC_START_SEQ_IDENT + app.startSeq}); 1828 } 1829 checkSlow(startTime, "startProcess: returned from zygote!"); 1830 return startResult; 1831 } finally { 1832 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER); 1833 } 1834 } 1835 1836 @GuardedBy("mService") 1837 final void startProcessLocked(ProcessRecord app, HostingRecord hostingRecord) { 1838 startProcessLocked(app, hostingRecord, null /* abiOverride */); 1839 } 1840 1841 @GuardedBy("mService") 1842 final boolean startProcessLocked(ProcessRecord app, HostingRecord hostingRecord, 1843 String abiOverride) { 1844 return startProcessLocked(app, hostingRecord, 1845 false /* disableHiddenApiChecks */, false /* mountExtStorageFull */, abiOverride); 1846 } 1847 1848 @GuardedBy("mService") 1849 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info, 1850 boolean knownToBeDead, int intentFlags, HostingRecord hostingRecord, 1851 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, 1852 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) { 1853 long startTime = SystemClock.elapsedRealtime(); 1854 ProcessRecord app; 1855 if (!isolated) { 1856 app = getProcessRecordLocked(processName, info.uid, keepIfLarge); 1857 checkSlow(startTime, "startProcess: after getProcessRecord"); 1858 1859 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) { 1860 // If we are in the background, then check to see if this process 1861 // is bad. If so, we will just silently fail. 1862 if (mService.mAppErrors.isBadProcessLocked(info)) { 1863 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid 1864 + "/" + info.processName); 1865 return null; 1866 } 1867 } else { 1868 // When the user is explicitly starting a process, then clear its 1869 // crash count so that we won't make it bad until they see at 1870 // least one crash dialog again, and make the process good again 1871 // if it had been bad. 1872 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid 1873 + "/" + info.processName); 1874 mService.mAppErrors.resetProcessCrashTimeLocked(info); 1875 if (mService.mAppErrors.isBadProcessLocked(info)) { 1876 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD, 1877 UserHandle.getUserId(info.uid), info.uid, 1878 info.processName); 1879 mService.mAppErrors.clearBadProcessLocked(info); 1880 if (app != null) { 1881 app.bad = false; 1882 } 1883 } 1884 } 1885 } else { 1886 // If this is an isolated process, it can't re-use an existing process. 1887 app = null; 1888 } 1889 1890 // We don't have to do anything more if: 1891 // (1) There is an existing application record; and 1892 // (2) The caller doesn't think it is dead, OR there is no thread 1893 // object attached to it so we know it couldn't have crashed; and 1894 // (3) There is a pid assigned to it, so it is either starting or 1895 // already running. 1896 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName 1897 + " app=" + app + " knownToBeDead=" + knownToBeDead 1898 + " thread=" + (app != null ? app.thread : null) 1899 + " pid=" + (app != null ? app.pid : -1)); 1900 if (app != null && app.pid > 0) { 1901 if ((!knownToBeDead && !app.killed) || app.thread == null) { 1902 // We already have the app running, or are waiting for it to 1903 // come up (we have a pid but not yet its thread), so keep it. 1904 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app); 1905 // If this is a new package in the process, add the package to the list 1906 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats); 1907 checkSlow(startTime, "startProcess: done, added package to proc"); 1908 return app; 1909 } 1910 1911 // An application record is attached to a previous process, 1912 // clean it up now. 1913 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App died: " + app); 1914 checkSlow(startTime, "startProcess: bad proc running, killing"); 1915 ProcessList.killProcessGroup(app.uid, app.pid); 1916 mService.handleAppDiedLocked(app, true, true); 1917 checkSlow(startTime, "startProcess: done killing old proc"); 1918 } 1919 1920 if (app == null) { 1921 checkSlow(startTime, "startProcess: creating new process record"); 1922 app = newProcessRecordLocked(info, processName, isolated, isolatedUid, hostingRecord); 1923 if (app == null) { 1924 Slog.w(TAG, "Failed making new process record for " 1925 + processName + "/" + info.uid + " isolated=" + isolated); 1926 return null; 1927 } 1928 app.crashHandler = crashHandler; 1929 app.isolatedEntryPoint = entryPoint; 1930 app.isolatedEntryPointArgs = entryPointArgs; 1931 checkSlow(startTime, "startProcess: done creating new process record"); 1932 } else { 1933 // If this is a new package in the process, add the package to the list 1934 app.addPackage(info.packageName, info.longVersionCode, mService.mProcessStats); 1935 checkSlow(startTime, "startProcess: added package to existing proc"); 1936 } 1937 1938 // If the system is not ready yet, then hold off on starting this 1939 // process until it is. 1940 if (!mService.mProcessesReady 1941 && !mService.isAllowedWhileBooting(info) 1942 && !allowWhileBooting) { 1943 if (!mService.mProcessesOnHold.contains(app)) { 1944 mService.mProcessesOnHold.add(app); 1945 } 1946 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, 1947 "System not ready, putting on hold: " + app); 1948 checkSlow(startTime, "startProcess: returning with proc on hold"); 1949 return app; 1950 } 1951 1952 checkSlow(startTime, "startProcess: stepping in to startProcess"); 1953 final boolean success = startProcessLocked(app, hostingRecord, abiOverride); 1954 checkSlow(startTime, "startProcess: done starting proc!"); 1955 return success ? app : null; 1956 } 1957 1958 @GuardedBy("mService") 1959 private String isProcStartValidLocked(ProcessRecord app, long expectedStartSeq) { 1960 StringBuilder sb = null; 1961 if (app.killedByAm) { 1962 if (sb == null) sb = new StringBuilder(); 1963 sb.append("killedByAm=true;"); 1964 } 1965 if (mProcessNames.get(app.processName, app.uid) != app) { 1966 if (sb == null) sb = new StringBuilder(); 1967 sb.append("No entry in mProcessNames;"); 1968 } 1969 if (!app.pendingStart) { 1970 if (sb == null) sb = new StringBuilder(); 1971 sb.append("pendingStart=false;"); 1972 } 1973 if (app.startSeq > expectedStartSeq) { 1974 if (sb == null) sb = new StringBuilder(); 1975 sb.append("seq=" + app.startSeq + ",expected=" + expectedStartSeq + ";"); 1976 } 1977 return sb == null ? null : sb.toString(); 1978 } 1979 1980 @GuardedBy("mService") 1981 private boolean handleProcessStartedLocked(ProcessRecord pending, 1982 Process.ProcessStartResult startResult, long expectedStartSeq) { 1983 // Indicates that this process start has been taken care of. 1984 if (mPendingStarts.get(expectedStartSeq) == null) { 1985 if (pending.pid == startResult.pid) { 1986 pending.setUsingWrapper(startResult.usingWrapper); 1987 // TODO: Update already existing clients of usingWrapper 1988 } 1989 return false; 1990 } 1991 return handleProcessStartedLocked(pending, startResult.pid, startResult.usingWrapper, 1992 expectedStartSeq, false); 1993 } 1994 1995 @GuardedBy("mService") 1996 boolean handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper, 1997 long expectedStartSeq, boolean procAttached) { 1998 mPendingStarts.remove(expectedStartSeq); 1999 final String reason = isProcStartValidLocked(app, expectedStartSeq); 2000 if (reason != null) { 2001 Slog.w(TAG_PROCESSES, app + " start not valid, killing pid=" + 2002 pid 2003 + ", " + reason); 2004 app.pendingStart = false; 2005 killProcessQuiet(pid); 2006 Process.killProcessGroup(app.uid, app.pid); 2007 return false; 2008 } 2009 mService.mBatteryStatsService.noteProcessStart(app.processName, app.info.uid); 2010 checkSlow(app.startTime, "startProcess: done updating battery stats"); 2011 2012 EventLog.writeEvent(EventLogTags.AM_PROC_START, 2013 UserHandle.getUserId(app.startUid), pid, app.startUid, 2014 app.processName, app.hostingRecord.getType(), 2015 app.hostingRecord.getName() != null ? app.hostingRecord.getName() : ""); 2016 2017 try { 2018 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid, 2019 app.seInfo, app.info.sourceDir, pid); 2020 } catch (RemoteException ex) { 2021 // Ignore 2022 } 2023 2024 if (app.isPersistent()) { 2025 Watchdog.getInstance().processStarted(app.processName, pid); 2026 } 2027 2028 checkSlow(app.startTime, "startProcess: building log message"); 2029 StringBuilder buf = mStringBuilder; 2030 buf.setLength(0); 2031 buf.append("Start proc "); 2032 buf.append(pid); 2033 buf.append(':'); 2034 buf.append(app.processName); 2035 buf.append('/'); 2036 UserHandle.formatUid(buf, app.startUid); 2037 if (app.isolatedEntryPoint != null) { 2038 buf.append(" ["); 2039 buf.append(app.isolatedEntryPoint); 2040 buf.append("]"); 2041 } 2042 buf.append(" for "); 2043 buf.append(app.hostingRecord.getType()); 2044 if (app.hostingRecord.getName() != null) { 2045 buf.append(" "); 2046 buf.append(app.hostingRecord.getName()); 2047 } 2048 mService.reportUidInfoMessageLocked(TAG, buf.toString(), app.startUid); 2049 app.setPid(pid); 2050 app.setUsingWrapper(usingWrapper); 2051 app.pendingStart = false; 2052 checkSlow(app.startTime, "startProcess: starting to update pids map"); 2053 ProcessRecord oldApp; 2054 synchronized (mService.mPidsSelfLocked) { 2055 oldApp = mService.mPidsSelfLocked.get(pid); 2056 } 2057 // If there is already an app occupying that pid that hasn't been cleaned up 2058 if (oldApp != null && !app.isolated) { 2059 // Clean up anything relating to this pid first 2060 Slog.wtf(TAG, "handleProcessStartedLocked process:" + app.processName 2061 + " startSeq:" + app.startSeq 2062 + " pid:" + pid 2063 + " belongs to another existing app:" + oldApp.processName 2064 + " startSeq:" + oldApp.startSeq); 2065 mService.cleanUpApplicationRecordLocked(oldApp, false, false, -1, 2066 true /*replacingPid*/); 2067 } 2068 mService.mPidsSelfLocked.put(app); 2069 synchronized (mService.mPidsSelfLocked) { 2070 if (!procAttached) { 2071 Message msg = mService.mHandler.obtainMessage(PROC_START_TIMEOUT_MSG); 2072 msg.obj = app; 2073 mService.mHandler.sendMessageDelayed(msg, usingWrapper 2074 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT); 2075 } 2076 } 2077 checkSlow(app.startTime, "startProcess: done updating pids map"); 2078 return true; 2079 } 2080 2081 final void removeLruProcessLocked(ProcessRecord app) { 2082 int lrui = mLruProcesses.lastIndexOf(app); 2083 if (lrui >= 0) { 2084 if (!app.killed) { 2085 if (app.isPersistent()) { 2086 Slog.w(TAG, "Removing persistent process that hasn't been killed: " + app); 2087 } else { 2088 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app); 2089 if (app.pid > 0) { 2090 killProcessQuiet(app.pid); 2091 ProcessList.killProcessGroup(app.uid, app.pid); 2092 } else { 2093 app.pendingStart = false; 2094 } 2095 } 2096 } 2097 if (lrui <= mLruProcessActivityStart) { 2098 mLruProcessActivityStart--; 2099 } 2100 if (lrui <= mLruProcessServiceStart) { 2101 mLruProcessServiceStart--; 2102 } 2103 mLruProcesses.remove(lrui); 2104 } 2105 } 2106 2107 @GuardedBy("mService") 2108 boolean killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj, 2109 String reason) { 2110 return killPackageProcessesLocked(packageName, appId, userId, minOomAdj, 2111 false /* callerWillRestart */, true /* allowRestart */, true /* doit */, 2112 false /* evenPersistent */, false /* setRemoved */, reason); 2113 } 2114 2115 @GuardedBy("mService") 2116 final boolean killPackageProcessesLocked(String packageName, int appId, 2117 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, 2118 boolean doit, boolean evenPersistent, boolean setRemoved, String reason) { 2119 ArrayList<ProcessRecord> procs = new ArrayList<>(); 2120 2121 // Remove all processes this package may have touched: all with the 2122 // same UID (except for the system or root user), and all whose name 2123 // matches the package name. 2124 final int NP = mProcessNames.getMap().size(); 2125 for (int ip = 0; ip < NP; ip++) { 2126 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2127 final int NA = apps.size(); 2128 for (int ia = 0; ia < NA; ia++) { 2129 ProcessRecord app = apps.valueAt(ia); 2130 if (app.isPersistent() && !evenPersistent) { 2131 // we don't kill persistent processes 2132 continue; 2133 } 2134 if (app.removed) { 2135 if (doit) { 2136 procs.add(app); 2137 } 2138 continue; 2139 } 2140 2141 // Skip process if it doesn't meet our oom adj requirement. 2142 if (app.setAdj < minOomAdj) { 2143 // Note it is still possible to have a process with oom adj 0 in the killed 2144 // processes, but it does not mean misjudgment. E.g. a bound service process 2145 // and its client activity process are both in the background, so they are 2146 // collected to be killed. If the client activity is killed first, the service 2147 // may be scheduled to unbind and become an executing service (oom adj 0). 2148 continue; 2149 } 2150 2151 // If no package is specified, we call all processes under the 2152 // give user id. 2153 if (packageName == null) { 2154 if (userId != UserHandle.USER_ALL && app.userId != userId) { 2155 continue; 2156 } 2157 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) { 2158 continue; 2159 } 2160 // Package has been specified, we want to hit all processes 2161 // that match it. We need to qualify this by the processes 2162 // that are running under the specified app and user ID. 2163 } else { 2164 final boolean isDep = app.pkgDeps != null 2165 && app.pkgDeps.contains(packageName); 2166 if (!isDep && UserHandle.getAppId(app.uid) != appId) { 2167 continue; 2168 } 2169 if (userId != UserHandle.USER_ALL && app.userId != userId) { 2170 continue; 2171 } 2172 if (!app.pkgList.containsKey(packageName) && !isDep) { 2173 continue; 2174 } 2175 } 2176 2177 // Process has passed all conditions, kill it! 2178 if (!doit) { 2179 return true; 2180 } 2181 if (setRemoved) { 2182 app.removed = true; 2183 } 2184 procs.add(app); 2185 } 2186 } 2187 2188 int N = procs.size(); 2189 for (int i=0; i<N; i++) { 2190 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason); 2191 } 2192 // See if there are any app zygotes running for this packageName / UID combination, 2193 // and kill it if so. 2194 final ArrayList<AppZygote> zygotesToKill = new ArrayList<>(); 2195 for (SparseArray<AppZygote> appZygotes : mAppZygotes.getMap().values()) { 2196 for (int i = 0; i < appZygotes.size(); ++i) { 2197 final int appZygoteUid = appZygotes.keyAt(i); 2198 if (userId != UserHandle.USER_ALL && UserHandle.getUserId(appZygoteUid) != userId) { 2199 continue; 2200 } 2201 if (appId >= 0 && UserHandle.getAppId(appZygoteUid) != appId) { 2202 continue; 2203 } 2204 final AppZygote appZygote = appZygotes.valueAt(i); 2205 if (packageName != null 2206 && !packageName.equals(appZygote.getAppInfo().packageName)) { 2207 continue; 2208 } 2209 zygotesToKill.add(appZygote); 2210 } 2211 } 2212 for (AppZygote appZygote : zygotesToKill) { 2213 killAppZygoteIfNeededLocked(appZygote); 2214 } 2215 mService.updateOomAdjLocked(OomAdjuster.OOM_ADJ_REASON_PROCESS_END); 2216 return N > 0; 2217 } 2218 2219 @GuardedBy("mService") 2220 boolean removeProcessLocked(ProcessRecord app, 2221 boolean callerWillRestart, boolean allowRestart, String reason) { 2222 final String name = app.processName; 2223 final int uid = app.uid; 2224 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES, 2225 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")"); 2226 2227 ProcessRecord old = mProcessNames.get(name, uid); 2228 if (old != app) { 2229 // This process is no longer active, so nothing to do. 2230 Slog.w(TAG, "Ignoring remove of inactive process: " + app); 2231 return false; 2232 } 2233 removeProcessNameLocked(name, uid); 2234 mService.mAtmInternal.clearHeavyWeightProcessIfEquals(app.getWindowProcessController()); 2235 2236 boolean needRestart = false; 2237 if ((app.pid > 0 && app.pid != ActivityManagerService.MY_PID) || (app.pid == 0 && app 2238 .pendingStart)) { 2239 int pid = app.pid; 2240 if (pid > 0) { 2241 mService.mPidsSelfLocked.remove(app); 2242 mService.mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app); 2243 mService.mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid); 2244 if (app.isolated) { 2245 mService.mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid); 2246 mService.getPackageManagerInternalLocked().removeIsolatedUid(app.uid); 2247 } 2248 } 2249 boolean willRestart = false; 2250 if (app.isPersistent() && !app.isolated) { 2251 if (!callerWillRestart) { 2252 willRestart = true; 2253 } else { 2254 needRestart = true; 2255 } 2256 } 2257 app.kill(reason, true); 2258 mService.handleAppDiedLocked(app, willRestart, allowRestart); 2259 if (willRestart) { 2260 removeLruProcessLocked(app); 2261 mService.addAppLocked(app.info, null, false, null /* ABI override */); 2262 } 2263 } else { 2264 mRemovedProcesses.add(app); 2265 } 2266 2267 return needRestart; 2268 } 2269 2270 @GuardedBy("mService") 2271 final void addProcessNameLocked(ProcessRecord proc) { 2272 // We shouldn't already have a process under this name, but just in case we 2273 // need to clean up whatever may be there now. 2274 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid); 2275 if (old == proc && proc.isPersistent()) { 2276 // We are re-adding a persistent process. Whatevs! Just leave it there. 2277 Slog.w(TAG, "Re-adding persistent process " + proc); 2278 } else if (old != null) { 2279 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc); 2280 } 2281 UidRecord uidRec = mActiveUids.get(proc.uid); 2282 if (uidRec == null) { 2283 uidRec = new UidRecord(proc.uid); 2284 // This is the first appearance of the uid, report it now! 2285 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 2286 "Creating new process uid: " + uidRec); 2287 if (Arrays.binarySearch(mService.mDeviceIdleTempWhitelist, 2288 UserHandle.getAppId(proc.uid)) >= 0 2289 || mService.mPendingTempWhitelist.indexOfKey(proc.uid) >= 0) { 2290 uidRec.setWhitelist = uidRec.curWhitelist = true; 2291 } 2292 uidRec.updateHasInternetPermission(); 2293 mActiveUids.put(proc.uid, uidRec); 2294 EventLogTags.writeAmUidRunning(uidRec.uid); 2295 mService.noteUidProcessState(uidRec.uid, uidRec.getCurProcState()); 2296 } 2297 proc.uidRecord = uidRec; 2298 2299 // Reset render thread tid if it was already set, so new process can set it again. 2300 proc.renderThreadTid = 0; 2301 uidRec.numProcs++; 2302 mProcessNames.put(proc.processName, proc.uid, proc); 2303 if (proc.isolated) { 2304 mIsolatedProcesses.put(proc.uid, proc); 2305 } 2306 } 2307 2308 @GuardedBy("mService") 2309 private IsolatedUidRange getOrCreateIsolatedUidRangeLocked(ApplicationInfo info, 2310 HostingRecord hostingRecord) { 2311 if (hostingRecord == null || !hostingRecord.usesAppZygote()) { 2312 // Allocate an isolated UID from the global range 2313 return mGlobalIsolatedUids; 2314 } else { 2315 return mAppIsolatedUidRangeAllocator.getOrCreateIsolatedUidRangeLocked( 2316 info.processName, hostingRecord.getDefiningUid()); 2317 } 2318 } 2319 2320 @GuardedBy("mService") 2321 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess, 2322 boolean isolated, int isolatedUid, HostingRecord hostingRecord) { 2323 String proc = customProcess != null ? customProcess : info.processName; 2324 final int userId = UserHandle.getUserId(info.uid); 2325 int uid = info.uid; 2326 if (isolated) { 2327 if (isolatedUid == 0) { 2328 IsolatedUidRange uidRange = getOrCreateIsolatedUidRangeLocked(info, hostingRecord); 2329 if (uidRange == null) { 2330 return null; 2331 } 2332 uid = uidRange.allocateIsolatedUidLocked(userId); 2333 if (uid == -1) { 2334 return null; 2335 } 2336 } else { 2337 // Special case for startIsolatedProcess (internal only), where 2338 // the uid of the isolated process is specified by the caller. 2339 uid = isolatedUid; 2340 } 2341 mService.getPackageManagerInternalLocked().addIsolatedUid(uid, info.uid); 2342 2343 // Register the isolated UID with this application so BatteryStats knows to 2344 // attribute resource usage to the application. 2345 // 2346 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats 2347 // about the process state of the isolated UID *before* it is registered with the 2348 // owning application. 2349 mService.mBatteryStatsService.addIsolatedUid(uid, info.uid); 2350 StatsLog.write(StatsLog.ISOLATED_UID_CHANGED, info.uid, uid, 2351 StatsLog.ISOLATED_UID_CHANGED__EVENT__CREATED); 2352 } 2353 final ProcessRecord r = new ProcessRecord(mService, info, proc, uid); 2354 2355 if (!mService.mBooted && !mService.mBooting 2356 && userId == UserHandle.USER_SYSTEM 2357 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) { 2358 // The system process is initialized to SCHED_GROUP_DEFAULT in init.rc. 2359 r.setCurrentSchedulingGroup(ProcessList.SCHED_GROUP_DEFAULT); 2360 r.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT; 2361 r.setPersistent(true); 2362 r.maxAdj = ProcessList.PERSISTENT_PROC_ADJ; 2363 } 2364 if (isolated && isolatedUid != 0) { 2365 // Special case for startIsolatedProcess (internal only) - assume the process 2366 // is required by the system server to prevent it being killed. 2367 r.maxAdj = ProcessList.PERSISTENT_SERVICE_ADJ; 2368 } 2369 addProcessNameLocked(r); 2370 return r; 2371 } 2372 2373 @GuardedBy("mService") 2374 final ProcessRecord removeProcessNameLocked(final String name, final int uid) { 2375 return removeProcessNameLocked(name, uid, null); 2376 } 2377 2378 @GuardedBy("mService") 2379 final ProcessRecord removeProcessNameLocked(final String name, final int uid, 2380 final ProcessRecord expecting) { 2381 ProcessRecord old = mProcessNames.get(name, uid); 2382 // Only actually remove when the currently recorded value matches the 2383 // record that we expected; if it doesn't match then we raced with a 2384 // newly created process and we don't want to destroy the new one. 2385 if ((expecting == null) || (old == expecting)) { 2386 mProcessNames.remove(name, uid); 2387 } 2388 if (old != null && old.uidRecord != null) { 2389 old.uidRecord.numProcs--; 2390 if (old.uidRecord.numProcs == 0) { 2391 // No more processes using this uid, tell clients it is gone. 2392 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS, 2393 "No more processes in " + old.uidRecord); 2394 mService.enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE); 2395 EventLogTags.writeAmUidStopped(uid); 2396 mActiveUids.remove(uid); 2397 mService.noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT); 2398 } 2399 old.uidRecord = null; 2400 } 2401 mIsolatedProcesses.remove(uid); 2402 mGlobalIsolatedUids.freeIsolatedUidLocked(uid); 2403 // Remove the (expected) ProcessRecord from the app zygote 2404 final ProcessRecord record = expecting != null ? expecting : old; 2405 if (record != null && record.appZygote) { 2406 removeProcessFromAppZygoteLocked(record); 2407 } 2408 2409 return old; 2410 } 2411 2412 /** Call setCoreSettings on all LRU processes, with the new settings. */ 2413 @GuardedBy("mService") 2414 void updateCoreSettingsLocked(Bundle settings) { 2415 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 2416 ProcessRecord processRecord = mLruProcesses.get(i); 2417 try { 2418 if (processRecord.thread != null) { 2419 processRecord.thread.setCoreSettings(settings); 2420 } 2421 } catch (RemoteException re) { 2422 /* ignore */ 2423 } 2424 } 2425 } 2426 2427 /** 2428 * Kill all background processes except for ones with targetSdk lower than minTargetSdk and 2429 * procstate lower than maxProcState. 2430 * @param minTargetSdk 2431 * @param maxProcState 2432 */ 2433 @GuardedBy("mService") 2434 void killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState) { 2435 final ArrayList<ProcessRecord> procs = new ArrayList<>(); 2436 final int NP = mProcessNames.getMap().size(); 2437 for (int ip = 0; ip < NP; ip++) { 2438 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip); 2439 final int NA = apps.size(); 2440 for (int ia = 0; ia < NA; ia++) { 2441 final ProcessRecord app = apps.valueAt(ia); 2442 if (app.removed || ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk) 2443 && (maxProcState < 0 || app.setProcState > maxProcState))) { 2444 procs.add(app); 2445 } 2446 } 2447 } 2448 2449 final int N = procs.size(); 2450 for (int i = 0; i < N; i++) { 2451 removeProcessLocked(procs.get(i), false, true, "kill all background except"); 2452 } 2453 } 2454 2455 /** 2456 * Call updateTimePrefs on all LRU processes 2457 * @param timePref The time pref to pass to each process 2458 */ 2459 @GuardedBy("mService") 2460 void updateAllTimePrefsLocked(int timePref) { 2461 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 2462 ProcessRecord r = mLruProcesses.get(i); 2463 if (r.thread != null) { 2464 try { 2465 r.thread.updateTimePrefs(timePref); 2466 } catch (RemoteException ex) { 2467 Slog.w(TAG, "Failed to update preferences for: " 2468 + r.info.processName); 2469 } 2470 } 2471 } 2472 } 2473 2474 void setAllHttpProxy() { 2475 // Update the HTTP proxy for each application thread. 2476 synchronized (mService) { 2477 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) { 2478 ProcessRecord r = mLruProcesses.get(i); 2479 // Don't dispatch to isolated processes as they can't access ConnectivityManager and 2480 // don't have network privileges anyway. Exclude system server and update it 2481 // separately outside the AMS lock, to avoid deadlock with Connectivity Service. 2482 if (r.pid != ActivityManagerService.MY_PID && r.thread != null && !r.isolated) { 2483 try { 2484 r.thread.updateHttpProxy(); 2485 } catch (RemoteException ex) { 2486 Slog.w(TAG, "Failed to update http proxy for: " 2487 + r.info.processName); 2488 } 2489 } 2490 } 2491 } 2492 ActivityThread.updateHttpProxy(mService.mContext); 2493 } 2494 2495 @GuardedBy("mService") 2496 void clearAllDnsCacheLocked() { 2497 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 2498 ProcessRecord r = mLruProcesses.get(i); 2499 if (r.thread != null) { 2500 try { 2501 r.thread.clearDnsCache(); 2502 } catch (RemoteException ex) { 2503 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName); 2504 } 2505 } 2506 } 2507 } 2508 2509 @GuardedBy("mService") 2510 void handleAllTrustStorageUpdateLocked() { 2511 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 2512 ProcessRecord r = mLruProcesses.get(i); 2513 if (r.thread != null) { 2514 try { 2515 r.thread.handleTrustStorageUpdate(); 2516 } catch (RemoteException ex) { 2517 Slog.w(TAG, "Failed to handle trust storage update for: " + 2518 r.info.processName); 2519 } 2520 } 2521 } 2522 } 2523 2524 @GuardedBy("mService") 2525 int updateLruProcessInternalLocked(ProcessRecord app, long now, int index, 2526 int lruSeq, String what, Object obj, ProcessRecord srcApp) { 2527 app.lastActivityTime = now; 2528 2529 if (app.hasActivitiesOrRecentTasks()) { 2530 // Don't want to touch dependent processes that are hosting activities. 2531 return index; 2532 } 2533 2534 int lrui = mLruProcesses.lastIndexOf(app); 2535 if (lrui < 0) { 2536 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: " 2537 + what + " " + obj + " from " + srcApp); 2538 return index; 2539 } 2540 2541 if (lrui >= index) { 2542 // Don't want to cause this to move dependent processes *back* in the 2543 // list as if they were less frequently used. 2544 return index; 2545 } 2546 2547 if (lrui >= mLruProcessActivityStart && index < mLruProcessActivityStart) { 2548 // Don't want to touch dependent processes that are hosting activities. 2549 return index; 2550 } 2551 2552 mLruProcesses.remove(lrui); 2553 if (index > 0) { 2554 index--; 2555 } 2556 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index 2557 + " in LRU list: " + app); 2558 mLruProcesses.add(index, app); 2559 app.lruSeq = lruSeq; 2560 return index; 2561 } 2562 2563 /** 2564 * Handle the case where we are inserting a process hosting client activities: 2565 * Make sure any groups have their order match their importance, and take care of 2566 * distributing old clients across other activity processes so they can't spam 2567 * the LRU list. Processing of the list will be restricted by the indices provided, 2568 * and not extend out of them. 2569 * 2570 * @param topApp The app at the top that has just been inserted in to the list. 2571 * @param topI The position in the list where topApp was inserted; this is the start (at the 2572 * top) where we are going to do our processing. 2573 * @param bottomI The last position at which we will be processing; this is the end position 2574 * of whichever section of the LRU list we are in. Nothing past it will be 2575 * touched. 2576 * @param endIndex The current end of the top being processed. Typically topI - 1. That is, 2577 * where we are going to start potentially adjusting other entries in the list. 2578 */ 2579 private void updateClientActivitiesOrdering(final ProcessRecord topApp, final int topI, 2580 final int bottomI, int endIndex) { 2581 if (topApp.hasActivitiesOrRecentTasks() || topApp.treatLikeActivity 2582 || !topApp.hasClientActivities()) { 2583 // If this is not a special process that has client activities, then there is 2584 // nothing to do. 2585 return; 2586 } 2587 2588 final int uid = topApp.info.uid; 2589 if (topApp.connectionGroup > 0) { 2590 int endImportance = topApp.connectionImportance; 2591 for (int i = endIndex; i >= bottomI; i--) { 2592 final ProcessRecord subProc = mLruProcesses.get(i); 2593 if (subProc.info.uid == uid 2594 && subProc.connectionGroup == topApp.connectionGroup) { 2595 if (i == endIndex && subProc.connectionImportance >= endImportance) { 2596 // This process is already in the group, and its importance 2597 // is not as strong as the process before it, so keep it 2598 // correctly positioned in the group. 2599 if (DEBUG_LRU) Slog.d(TAG_LRU, 2600 "Keeping in-place above " + subProc 2601 + " endImportance=" + endImportance 2602 + " group=" + subProc.connectionGroup 2603 + " importance=" + subProc.connectionImportance); 2604 endIndex--; 2605 endImportance = subProc.connectionImportance; 2606 } else { 2607 // We want to pull this up to be with the rest of the group, 2608 // and order within the group by importance. 2609 if (DEBUG_LRU) Slog.d(TAG_LRU, 2610 "Pulling up " + subProc 2611 + " to position in group with importance=" 2612 + subProc.connectionImportance); 2613 boolean moved = false; 2614 for (int pos = topI; pos > endIndex; pos--) { 2615 final ProcessRecord posProc = mLruProcesses.get(pos); 2616 if (subProc.connectionImportance 2617 <= posProc.connectionImportance) { 2618 mLruProcesses.remove(i); 2619 mLruProcesses.add(pos, subProc); 2620 if (DEBUG_LRU) Slog.d(TAG_LRU, 2621 "Moving " + subProc 2622 + " from position " + i + " to above " + posProc 2623 + " @ " + pos); 2624 moved = true; 2625 endIndex--; 2626 break; 2627 } 2628 } 2629 if (!moved) { 2630 // Goes to the end of the group. 2631 mLruProcesses.remove(i); 2632 mLruProcesses.add(endIndex - 1, subProc); 2633 if (DEBUG_LRU) Slog.d(TAG_LRU, 2634 "Moving " + subProc 2635 + " from position " + i + " to end of group @ " 2636 + endIndex); 2637 endIndex--; 2638 endImportance = subProc.connectionImportance; 2639 } 2640 } 2641 } 2642 } 2643 2644 } 2645 // To keep it from spamming the LRU list (by making a bunch of clients), 2646 // we will distribute other entries owned by it to be in-between other apps. 2647 int i = endIndex; 2648 while (i >= bottomI) { 2649 ProcessRecord subProc = mLruProcesses.get(i); 2650 if (DEBUG_LRU) Slog.d(TAG_LRU, 2651 "Looking to spread old procs, at " + subProc + " @ " + i); 2652 if (subProc.info.uid != uid) { 2653 // This is a different app... if we have gone through some of the 2654 // target app, pull this up to be before them. We want to pull up 2655 // one activity process, but any number of non-activity processes. 2656 if (i < endIndex) { 2657 boolean hasActivity = false; 2658 int connUid = 0; 2659 int connGroup = 0; 2660 while (i >= bottomI) { 2661 mLruProcesses.remove(i); 2662 mLruProcesses.add(endIndex, subProc); 2663 if (DEBUG_LRU) Slog.d(TAG_LRU, 2664 "Different app, moving to " + endIndex); 2665 i--; 2666 if (i < bottomI) { 2667 break; 2668 } 2669 subProc = mLruProcesses.get(i); 2670 if (DEBUG_LRU) Slog.d(TAG_LRU, 2671 "Looking at next app at " + i + ": " + subProc); 2672 if (subProc.hasActivitiesOrRecentTasks() || subProc.treatLikeActivity) { 2673 if (DEBUG_LRU) Slog.d(TAG_LRU, 2674 "This is hosting an activity!"); 2675 if (hasActivity) { 2676 // Already found an activity, done. 2677 if (DEBUG_LRU) Slog.d(TAG_LRU, 2678 "Already found an activity, done"); 2679 break; 2680 } 2681 hasActivity = true; 2682 } else if (subProc.hasClientActivities()) { 2683 if (DEBUG_LRU) Slog.d(TAG_LRU, 2684 "This is a client of an activity"); 2685 if (hasActivity) { 2686 if (connUid == 0 || connUid != subProc.info.uid) { 2687 // Already have an activity that is not from from a client 2688 // connection or is a different client connection, done. 2689 if (DEBUG_LRU) Slog.d(TAG_LRU, 2690 "Already found a different activity: connUid=" 2691 + connUid + " uid=" + subProc.info.uid); 2692 break; 2693 } else if (connGroup == 0 || connGroup != subProc.connectionGroup) { 2694 // Previously saw a different group or not from a group, 2695 // want to treat these as different things. 2696 if (DEBUG_LRU) Slog.d(TAG_LRU, 2697 "Already found a different group: connGroup=" 2698 + connGroup + " group=" + subProc.connectionGroup); 2699 break; 2700 } 2701 } else { 2702 if (DEBUG_LRU) Slog.d(TAG_LRU, 2703 "This is an activity client! uid=" 2704 + subProc.info.uid + " group=" + subProc.connectionGroup); 2705 hasActivity = true; 2706 connUid = subProc.info.uid; 2707 connGroup = subProc.connectionGroup; 2708 } 2709 } 2710 endIndex--; 2711 } 2712 } 2713 // Find the end of the next group of processes for target app. This 2714 // is after any entries of different apps (so we don't change the existing 2715 // relative order of apps) and then after the next last group of processes 2716 // of the target app. 2717 for (endIndex--; endIndex >= bottomI; endIndex--) { 2718 final ProcessRecord endProc = mLruProcesses.get(endIndex); 2719 if (endProc.info.uid == uid) { 2720 if (DEBUG_LRU) Slog.d(TAG_LRU, 2721 "Found next group of app: " + endProc + " @ " 2722 + endIndex); 2723 break; 2724 } 2725 } 2726 if (endIndex >= bottomI) { 2727 final ProcessRecord endProc = mLruProcesses.get(endIndex); 2728 for (endIndex--; endIndex >= bottomI; endIndex--) { 2729 final ProcessRecord nextEndProc = mLruProcesses.get(endIndex); 2730 if (nextEndProc.info.uid != uid 2731 || nextEndProc.connectionGroup != endProc.connectionGroup) { 2732 if (DEBUG_LRU) Slog.d(TAG_LRU, 2733 "Found next group or app: " + nextEndProc + " @ " 2734 + endIndex + " group=" + nextEndProc.connectionGroup); 2735 break; 2736 } 2737 } 2738 } 2739 if (DEBUG_LRU) Slog.d(TAG_LRU, 2740 "Bumping scan position to " + endIndex); 2741 i = endIndex; 2742 } else { 2743 i--; 2744 } 2745 } 2746 } 2747 2748 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange, 2749 ProcessRecord client) { 2750 final boolean hasActivity = app.hasActivitiesOrRecentTasks() || app.hasClientActivities() 2751 || app.treatLikeActivity; 2752 final boolean hasService = false; // not impl yet. app.services.size() > 0; 2753 if (!activityChange && hasActivity) { 2754 // The process has activities, so we are only allowing activity-based adjustments 2755 // to move it. It should be kept in the front of the list with other 2756 // processes that have activities, and we don't want those to change their 2757 // order except due to activity operations. 2758 return; 2759 } 2760 2761 mLruSeq++; 2762 final long now = SystemClock.uptimeMillis(); 2763 app.lastActivityTime = now; 2764 2765 // First a quick reject: if the app is already at the position we will 2766 // put it, then there is nothing to do. 2767 if (hasActivity) { 2768 final int N = mLruProcesses.size(); 2769 if (N > 0 && mLruProcesses.get(N - 1) == app) { 2770 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app); 2771 return; 2772 } 2773 } else { 2774 if (mLruProcessServiceStart > 0 2775 && mLruProcesses.get(mLruProcessServiceStart-1) == app) { 2776 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app); 2777 return; 2778 } 2779 } 2780 2781 int lrui = mLruProcesses.lastIndexOf(app); 2782 2783 if (app.isPersistent() && lrui >= 0) { 2784 // We don't care about the position of persistent processes, as long as 2785 // they are in the list. 2786 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app); 2787 return; 2788 } 2789 2790 /* In progress: compute new position first, so we can avoid doing work 2791 if the process is not actually going to move. Not yet working. 2792 int addIndex; 2793 int nextIndex; 2794 boolean inActivity = false, inService = false; 2795 if (hasActivity) { 2796 // Process has activities, put it at the very tipsy-top. 2797 addIndex = mLruProcesses.size(); 2798 nextIndex = mLruProcessServiceStart; 2799 inActivity = true; 2800 } else if (hasService) { 2801 // Process has services, put it at the top of the service list. 2802 addIndex = mLruProcessActivityStart; 2803 nextIndex = mLruProcessServiceStart; 2804 inActivity = true; 2805 inService = true; 2806 } else { 2807 // Process not otherwise of interest, it goes to the top of the non-service area. 2808 addIndex = mLruProcessServiceStart; 2809 if (client != null) { 2810 int clientIndex = mLruProcesses.lastIndexOf(client); 2811 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating " 2812 + app); 2813 if (clientIndex >= 0 && addIndex > clientIndex) { 2814 addIndex = clientIndex; 2815 } 2816 } 2817 nextIndex = addIndex > 0 ? addIndex-1 : addIndex; 2818 } 2819 2820 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act=" 2821 + mLruProcessActivityStart + "): " + app); 2822 */ 2823 2824 if (lrui >= 0) { 2825 if (lrui < mLruProcessActivityStart) { 2826 mLruProcessActivityStart--; 2827 } 2828 if (lrui < mLruProcessServiceStart) { 2829 mLruProcessServiceStart--; 2830 } 2831 /* 2832 if (addIndex > lrui) { 2833 addIndex--; 2834 } 2835 if (nextIndex > lrui) { 2836 nextIndex--; 2837 } 2838 */ 2839 mLruProcesses.remove(lrui); 2840 } 2841 2842 /* 2843 mLruProcesses.add(addIndex, app); 2844 if (inActivity) { 2845 mLruProcessActivityStart++; 2846 } 2847 if (inService) { 2848 mLruProcessActivityStart++; 2849 } 2850 */ 2851 2852 int nextIndex; 2853 int nextActivityIndex = -1; 2854 if (hasActivity) { 2855 final int N = mLruProcesses.size(); 2856 nextIndex = mLruProcessServiceStart; 2857 if (!app.hasActivitiesOrRecentTasks() && !app.treatLikeActivity 2858 && mLruProcessActivityStart < (N - 1)) { 2859 // Process doesn't have activities, but has clients with 2860 // activities... move it up, but below the app that is binding to it. 2861 if (DEBUG_LRU) Slog.d(TAG_LRU, 2862 "Adding to second-top of LRU activity list: " + app 2863 + " group=" + app.connectionGroup 2864 + " importance=" + app.connectionImportance); 2865 int pos = N - 1; 2866 while (pos > mLruProcessActivityStart) { 2867 final ProcessRecord posproc = mLruProcesses.get(pos); 2868 if (posproc.info.uid == app.info.uid) { 2869 // Technically this app could have multiple processes with different 2870 // activities and so we should be looking for the actual process that 2871 // is bound to the target proc... but I don't really care, do you? 2872 break; 2873 } 2874 pos--; 2875 } 2876 mLruProcesses.add(pos, app); 2877 if (pos == mLruProcessActivityStart) { 2878 mLruProcessActivityStart++; 2879 } 2880 if (pos == mLruProcessServiceStart) { 2881 // Unless {@code #hasService} is implemented, currently the starting position 2882 // for activity and service are the same, so the incoming position may equal to 2883 // the starting position of service. 2884 mLruProcessServiceStart++; 2885 } 2886 // If this process is part of a group, need to pull up any other processes 2887 // in that group to be with it. 2888 int endIndex = pos - 1; 2889 if (endIndex < mLruProcessActivityStart) { 2890 endIndex = mLruProcessActivityStart; 2891 } 2892 nextActivityIndex = endIndex; 2893 updateClientActivitiesOrdering(app, pos, mLruProcessActivityStart, endIndex); 2894 } else { 2895 // Process has activities, put it at the very tipsy-top. 2896 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app); 2897 mLruProcesses.add(app); 2898 nextActivityIndex = mLruProcesses.size() - 1; 2899 } 2900 } else if (hasService) { 2901 // Process has services, put it at the top of the service list. 2902 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app); 2903 mLruProcesses.add(mLruProcessActivityStart, app); 2904 nextIndex = mLruProcessServiceStart; 2905 mLruProcessActivityStart++; 2906 } else { 2907 // Process not otherwise of interest, it goes to the top of the non-service area. 2908 int index = mLruProcessServiceStart; 2909 if (client != null) { 2910 // If there is a client, don't allow the process to be moved up higher 2911 // in the list than that client. 2912 int clientIndex = mLruProcesses.lastIndexOf(client); 2913 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client 2914 + " when updating " + app); 2915 if (clientIndex <= lrui) { 2916 // Don't allow the client index restriction to push it down farther in the 2917 // list than it already is. 2918 clientIndex = lrui; 2919 } 2920 if (clientIndex >= 0 && index > clientIndex) { 2921 index = clientIndex; 2922 } 2923 } 2924 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app); 2925 mLruProcesses.add(index, app); 2926 nextIndex = index - 1; 2927 mLruProcessActivityStart++; 2928 mLruProcessServiceStart++; 2929 if (index > 1) { 2930 updateClientActivitiesOrdering(app, mLruProcessServiceStart - 1, 0, index - 1); 2931 } 2932 } 2933 2934 app.lruSeq = mLruSeq; 2935 2936 // If the app is currently using a content provider or service, 2937 // bump those processes as well. 2938 for (int j = app.connections.size() - 1; j >= 0; j--) { 2939 ConnectionRecord cr = app.connections.valueAt(j); 2940 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null 2941 && cr.binding.service.app != null 2942 && cr.binding.service.app.lruSeq != mLruSeq 2943 && (cr.flags & Context.BIND_REDUCTION_FLAGS) == 0 2944 && !cr.binding.service.app.isPersistent()) { 2945 if (cr.binding.service.app.hasClientActivities()) { 2946 if (nextActivityIndex >= 0) { 2947 nextActivityIndex = updateLruProcessInternalLocked(cr.binding.service.app, 2948 now, 2949 nextActivityIndex, mLruSeq, 2950 "service connection", cr, app); 2951 } 2952 } else { 2953 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, 2954 now, 2955 nextIndex, mLruSeq, 2956 "service connection", cr, app); 2957 } 2958 } 2959 } 2960 for (int j = app.conProviders.size() - 1; j >= 0; j--) { 2961 ContentProviderRecord cpr = app.conProviders.get(j).provider; 2962 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.isPersistent()) { 2963 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex, mLruSeq, 2964 "provider reference", cpr, app); 2965 } 2966 } 2967 } 2968 2969 final ProcessRecord getLRURecordForAppLocked(IApplicationThread thread) { 2970 final IBinder threadBinder = thread.asBinder(); 2971 // Find the application record. 2972 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 2973 final ProcessRecord rec = mLruProcesses.get(i); 2974 if (rec.thread != null && rec.thread.asBinder() == threadBinder) { 2975 return rec; 2976 } 2977 } 2978 return null; 2979 } 2980 2981 boolean haveBackgroundProcessLocked() { 2982 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 2983 final ProcessRecord rec = mLruProcesses.get(i); 2984 if (rec.thread != null 2985 && rec.setProcState >= PROCESS_STATE_CACHED_ACTIVITY) { 2986 return true; 2987 } 2988 } 2989 return false; 2990 } 2991 2992 private static int procStateToImportance(int procState, int memAdj, 2993 ActivityManager.RunningAppProcessInfo currApp, 2994 int clientTargetSdk) { 2995 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportanceForTargetSdk( 2996 procState, clientTargetSdk); 2997 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) { 2998 currApp.lru = memAdj; 2999 } else { 3000 currApp.lru = 0; 3001 } 3002 return imp; 3003 } 3004 3005 @GuardedBy("mService") 3006 void fillInProcMemInfoLocked(ProcessRecord app, 3007 ActivityManager.RunningAppProcessInfo outInfo, 3008 int clientTargetSdk) { 3009 outInfo.pid = app.pid; 3010 outInfo.uid = app.info.uid; 3011 if (mService.mAtmInternal.isHeavyWeightProcess(app.getWindowProcessController())) { 3012 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE; 3013 } 3014 if (app.isPersistent()) { 3015 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT; 3016 } 3017 if (app.hasActivities()) { 3018 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES; 3019 } 3020 outInfo.lastTrimLevel = app.trimMemoryLevel; 3021 int adj = app.curAdj; 3022 int procState = app.getCurProcState(); 3023 outInfo.importance = procStateToImportance(procState, adj, outInfo, 3024 clientTargetSdk); 3025 outInfo.importanceReasonCode = app.adjTypeCode; 3026 outInfo.processState = app.getCurProcState(); 3027 outInfo.isFocused = (app == mService.getTopAppLocked()); 3028 outInfo.lastActivityTime = app.lastActivityTime; 3029 } 3030 3031 @GuardedBy("mService") 3032 List<ActivityManager.RunningAppProcessInfo> getRunningAppProcessesLocked(boolean allUsers, 3033 int userId, boolean allUids, int callingUid, int clientTargetSdk) { 3034 // Lazy instantiation of list 3035 List<ActivityManager.RunningAppProcessInfo> runList = null; 3036 3037 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3038 ProcessRecord app = mLruProcesses.get(i); 3039 if ((!allUsers && app.userId != userId) 3040 || (!allUids && app.uid != callingUid)) { 3041 continue; 3042 } 3043 if ((app.thread != null) && (!app.isCrashing() && !app.isNotResponding())) { 3044 // Generate process state info for running application 3045 ActivityManager.RunningAppProcessInfo currApp = 3046 new ActivityManager.RunningAppProcessInfo(app.processName, 3047 app.pid, app.getPackageList()); 3048 fillInProcMemInfoLocked(app, currApp, clientTargetSdk); 3049 if (app.adjSource instanceof ProcessRecord) { 3050 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid; 3051 currApp.importanceReasonImportance = 3052 ActivityManager.RunningAppProcessInfo.procStateToImportance( 3053 app.adjSourceProcState); 3054 } else if (app.adjSource instanceof ActivityServiceConnectionsHolder) { 3055 final ActivityServiceConnectionsHolder r = 3056 (ActivityServiceConnectionsHolder) app.adjSource; 3057 final int pid = r.getActivityPid(); 3058 if (pid != -1) { 3059 currApp.importanceReasonPid = pid; 3060 } 3061 } 3062 if (app.adjTarget instanceof ComponentName) { 3063 currApp.importanceReasonComponent = (ComponentName)app.adjTarget; 3064 } 3065 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance 3066 // + " lru=" + currApp.lru); 3067 if (runList == null) { 3068 runList = new ArrayList<>(); 3069 } 3070 runList.add(currApp); 3071 } 3072 } 3073 return runList; 3074 } 3075 3076 @GuardedBy("mService") 3077 int getLruSizeLocked() { 3078 return mLruProcesses.size(); 3079 } 3080 3081 @GuardedBy("mService") 3082 void dumpLruListHeaderLocked(PrintWriter pw) { 3083 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size()); 3084 pw.print(" total, non-act at "); 3085 pw.print(mLruProcesses.size() - mLruProcessActivityStart); 3086 pw.print(", non-svc at "); 3087 pw.print(mLruProcesses.size() - mLruProcessServiceStart); 3088 pw.println("):"); 3089 } 3090 3091 @GuardedBy("mService") 3092 ArrayList<ProcessRecord> collectProcessesLocked(int start, boolean allPkgs, String[] args) { 3093 ArrayList<ProcessRecord> procs; 3094 if (args != null && args.length > start 3095 && args[start].charAt(0) != '-') { 3096 procs = new ArrayList<ProcessRecord>(); 3097 int pid = -1; 3098 try { 3099 pid = Integer.parseInt(args[start]); 3100 } catch (NumberFormatException e) { 3101 } 3102 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3103 ProcessRecord proc = mLruProcesses.get(i); 3104 if (proc.pid > 0 && proc.pid == pid) { 3105 procs.add(proc); 3106 } else if (allPkgs && proc.pkgList != null 3107 && proc.pkgList.containsKey(args[start])) { 3108 procs.add(proc); 3109 } else if (proc.processName.equals(args[start])) { 3110 procs.add(proc); 3111 } 3112 } 3113 if (procs.size() <= 0) { 3114 return null; 3115 } 3116 } else { 3117 procs = new ArrayList<ProcessRecord>(mLruProcesses); 3118 } 3119 return procs; 3120 } 3121 3122 @GuardedBy("mService") 3123 void updateApplicationInfoLocked(List<String> packagesToUpdate, int userId, 3124 boolean updateFrameworkRes) { 3125 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3126 final ProcessRecord app = mLruProcesses.get(i); 3127 if (app.thread == null) { 3128 continue; 3129 } 3130 3131 if (userId != UserHandle.USER_ALL && app.userId != userId) { 3132 continue; 3133 } 3134 3135 final int packageCount = app.pkgList.size(); 3136 for (int j = 0; j < packageCount; j++) { 3137 final String packageName = app.pkgList.keyAt(j); 3138 if (updateFrameworkRes || packagesToUpdate.contains(packageName)) { 3139 try { 3140 final ApplicationInfo ai = AppGlobals.getPackageManager() 3141 .getApplicationInfo(packageName, STOCK_PM_FLAGS, app.userId); 3142 if (ai != null) { 3143 app.thread.scheduleApplicationInfoChanged(ai); 3144 } 3145 } catch (RemoteException e) { 3146 Slog.w(TAG, String.format("Failed to update %s ApplicationInfo for %s", 3147 packageName, app)); 3148 } 3149 } 3150 } 3151 } 3152 } 3153 3154 @GuardedBy("mService") 3155 void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) { 3156 boolean foundProcess = false; 3157 for (int i = mLruProcesses.size() - 1; i >= 0; i--) { 3158 ProcessRecord r = mLruProcesses.get(i); 3159 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) { 3160 try { 3161 for (int index = packages.length - 1; index >= 0 && !foundProcess; index--) { 3162 if (packages[index].equals(r.info.packageName)) { 3163 foundProcess = true; 3164 } 3165 } 3166 r.thread.dispatchPackageBroadcast(cmd, packages); 3167 } catch (RemoteException ex) { 3168 } 3169 } 3170 } 3171 3172 if (!foundProcess) { 3173 try { 3174 AppGlobals.getPackageManager().notifyPackagesReplacedReceived(packages); 3175 } catch (RemoteException ignored) { 3176 } 3177 } 3178 } 3179 3180 /** Returns the uid's process state or PROCESS_STATE_NONEXISTENT if not running */ 3181 @GuardedBy("mService") 3182 int getUidProcStateLocked(int uid) { 3183 UidRecord uidRec = mActiveUids.get(uid); 3184 return uidRec == null ? PROCESS_STATE_NONEXISTENT : uidRec.getCurProcState(); 3185 } 3186 3187 /** Returns the UidRecord for the given uid, if it exists. */ 3188 @GuardedBy("mService") 3189 UidRecord getUidRecordLocked(int uid) { 3190 return mActiveUids.get(uid); 3191 } 3192 3193 /** 3194 * Call {@link ActivityManagerService#doStopUidLocked} 3195 * (which will also stop background services) for all idle UIDs. 3196 */ 3197 @GuardedBy("mService") 3198 void doStopUidForIdleUidsLocked() { 3199 final int size = mActiveUids.size(); 3200 for (int i = 0; i < size; i++) { 3201 final int uid = mActiveUids.keyAt(i); 3202 if (UserHandle.isCore(uid)) { 3203 continue; 3204 } 3205 final UidRecord uidRec = mActiveUids.valueAt(i); 3206 if (!uidRec.idle) { 3207 continue; 3208 } 3209 mService.doStopUidLocked(uidRec.uid, uidRec); 3210 } 3211 } 3212 } 3213