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 IsolatedUidRange(int firstUid, int lastUid)399 IsolatedUidRange(int firstUid, int lastUid) { 400 mFirstUid = firstUid; 401 mLastUid = lastUid; 402 mNextUid = firstUid; 403 } 404 405 @GuardedBy("ProcessList.this.mService") allocateIsolatedUidLocked(int userId)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") freeIsolatedUidLocked(int uid)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 IsolatedUidRangeAllocator(int firstUid, int lastUid, int numUidsPerRange)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") getIsolatedUidRangeLocked(String processName, int uid)457 IsolatedUidRange getIsolatedUidRangeLocked(String processName, int uid) { 458 return mAppRanges.get(processName, uid); 459 } 460 461 @GuardedBy("ProcessList.this.mService") getOrCreateIsolatedUidRangeLocked(String processName, int uid)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") freeUidRangeLocked(ApplicationInfo info)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 put(String name, int uid, ProcessRecord value)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 remove(String name, int uid)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 KillHandler(Looper looper)540 public KillHandler(Looper looper) { 541 super(looper, null, true); 542 } 543 544 @Override handleMessage(Message msg)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 ProcessList()561 ProcessList() { 562 MemInfoReader minfo = new MemInfoReader(); 563 minfo.readMemInfo(); 564 mTotalMemMb = minfo.getTotalSize()/(1024*1024); 565 updateOomLevels(0, 0, false); 566 } 567 init(ActivityManagerService service, ActiveUids activeUids)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 applyDisplaySize(WindowManagerService wm)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 updateOomLevels(int displayWidth, int displayHeight, boolean write)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 computeEmptyProcessLimit(int totalProcessLimit)687 public static int computeEmptyProcessLimit(int totalProcessLimit) { 688 return totalProcessLimit/2; 689 } 690 buildOomTag(String prefix, String compactPrefix, String space, int val, int base, boolean compact)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 makeOomAdjString(int setAdj, boolean compact)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 makeProcStateString(int curProcState)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 makeProcStateProtoEnum(int curProcState)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 appendRamKb(StringBuilder sb, long ramKb)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 ProcStateMemTracker()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 dumpLine(PrintWriter pw)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 procStatesDifferForMem(int procState1, int procState2)1093 public static boolean procStatesDifferForMem(int procState1, int procState2) { 1094 return sProcStateToProcMem[procState1] != sProcStateToProcMem[procState2]; 1095 } 1096 minTimeFromStateChange(boolean test)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 commitNextPssTime(ProcStateMemTracker tracker)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 abortNextPssTime(ProcStateMemTracker tracker)1110 public static void abortNextPssTime(ProcStateMemTracker tracker) { 1111 tracker.mPendingMemState = -1; 1112 } 1113 computeNextPssTime(int procState, ProcStateMemTracker tracker, boolean test, boolean sleeping, long now)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.isCore(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 getMemoryInfo(ActivityManager.MemoryInfo outInfo)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") isProcStartValidLocked(ProcessRecord app, long expectedStartSeq)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") handleProcessStartedLocked(ProcessRecord pending, Process.ProcessStartResult startResult, long expectedStartSeq)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") handleProcessStartedLocked(ProcessRecord app, int pid, boolean usingWrapper, long expectedStartSeq, boolean procAttached)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 removeLruProcessLocked(ProcessRecord app)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") killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj, String reason)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") killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, boolean evenPersistent, boolean setRemoved, String reason)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") removeProcessLocked(ProcessRecord app, boolean callerWillRestart, boolean allowRestart, String reason)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") addProcessNameLocked(ProcessRecord proc)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") getOrCreateIsolatedUidRangeLocked(ApplicationInfo info, HostingRecord hostingRecord)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") newProcessRecordLocked(ApplicationInfo info, String customProcess, boolean isolated, int isolatedUid, HostingRecord hostingRecord)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") removeProcessNameLocked(final String name, final int uid)2374 final ProcessRecord removeProcessNameLocked(final String name, final int uid) { 2375 return removeProcessNameLocked(name, uid, null); 2376 } 2377 2378 @GuardedBy("mService") removeProcessNameLocked(final String name, final int uid, final ProcessRecord expecting)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") updateCoreSettingsLocked(Bundle settings)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") killAllBackgroundProcessesExceptLocked(int minTargetSdk, int maxProcState)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") updateAllTimePrefsLocked(int timePref)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 setAllHttpProxy()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") clearAllDnsCacheLocked()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") handleAllTrustStorageUpdateLocked()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") updateLruProcessInternalLocked(ProcessRecord app, long now, int index, int lruSeq, String what, Object obj, ProcessRecord srcApp)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 */ updateClientActivitiesOrdering(final ProcessRecord topApp, final int topI, final int bottomI, int endIndex)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 updateLruProcessLocked(ProcessRecord app, boolean activityChange, ProcessRecord client)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 getLRURecordForAppLocked(IApplicationThread thread)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 haveBackgroundProcessLocked()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 procStateToImportance(int procState, int memAdj, ActivityManager.RunningAppProcessInfo currApp, int clientTargetSdk)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") fillInProcMemInfoLocked(ProcessRecord app, ActivityManager.RunningAppProcessInfo outInfo, int clientTargetSdk)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") getRunningAppProcessesLocked(boolean allUsers, int userId, boolean allUids, int callingUid, int clientTargetSdk)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") getLruSizeLocked()3077 int getLruSizeLocked() { 3078 return mLruProcesses.size(); 3079 } 3080 3081 @GuardedBy("mService") dumpLruListHeaderLocked(PrintWriter pw)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") collectProcessesLocked(int start, boolean allPkgs, String[] args)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") updateApplicationInfoLocked(List<String> packagesToUpdate, int userId, boolean updateFrameworkRes)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") sendPackageBroadcastLocked(int cmd, String[] packages, int userId)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") getUidProcStateLocked(int uid)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") getUidRecordLocked(int uid)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") doStopUidForIdleUidsLocked()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