ProcessRecord.java revision f1cca18ae460b66242988a8a6204c4a42b6fa1c1
1/* 2 * Copyright (C) 2006 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 17package com.android.server.am; 18 19import android.util.ArraySet; 20import com.android.internal.os.BatteryStatsImpl; 21 22import android.app.ActivityManager; 23import android.app.Dialog; 24import android.app.IApplicationThread; 25import android.app.IInstrumentationWatcher; 26import android.app.IUiAutomationConnection; 27import android.content.ComponentName; 28import android.content.Context; 29import android.content.pm.ApplicationInfo; 30import android.content.res.CompatibilityInfo; 31import android.os.Bundle; 32import android.os.IBinder; 33import android.os.Process; 34import android.os.SystemClock; 35import android.os.UserHandle; 36import android.util.ArrayMap; 37import android.util.PrintWriterPrinter; 38import android.util.TimeUtils; 39 40import java.io.PrintWriter; 41import java.util.ArrayList; 42 43/** 44 * Full information about a particular process that 45 * is currently running. 46 */ 47final class ProcessRecord { 48 final BatteryStatsImpl.Uid.Proc batteryStats; // where to collect runtime statistics 49 final ApplicationInfo info; // all about the first app in the process 50 final boolean isolated; // true if this is a special isolated process 51 final int uid; // uid of process; may be different from 'info' if isolated 52 final int userId; // user of process. 53 final String processName; // name of the process 54 final ProcessTracker.ProcessState baseProcessTracker; 55 // List of packages running in the process 56 final ArrayMap<String, ProcessTracker.ProcessState> pkgList 57 = new ArrayMap<String, ProcessTracker.ProcessState>(); 58 IApplicationThread thread; // the actual proc... may be null only if 59 // 'persistent' is true (in which case we 60 // are in the process of launching the app) 61 int pid; // The process of this application; 0 if none 62 boolean starting; // True if the process is being started 63 long lastActivityTime; // For managing the LRU list 64 long lruWeight; // Weight for ordering in LRU list 65 long lastPssTime; // Last time we retrieved PSS data 66 long nextPssTime; // Next time we want to request PSS data 67 long lastStateTime; // Last time setProcState changed 68 int maxAdj; // Maximum OOM adjustment for this process 69 int curRawAdj; // Current OOM unlimited adjustment for this process 70 int setRawAdj; // Last set OOM unlimited adjustment for this process 71 int curAdj; // Current OOM adjustment for this process 72 int setAdj; // Last set OOM adjustment for this process 73 int curSchedGroup; // Currently desired scheduling class 74 int setSchedGroup; // Last set to background scheduling class 75 int trimMemoryLevel; // Last selected memory trimming level 76 int memImportance; // Importance constant computed from curAdj 77 int curProcState = -1; // Currently computed process state: ActivityManager.PROCESS_STATE_* 78 int repProcState = -1; // Last reported process state 79 int setProcState = -1; // Last set process state in process tracker 80 int pssProcState = -1; // The proc state we are currently requesting pss for 81 boolean serviceb; // Process currently is on the service B list 82 boolean keeping; // Actively running code so don't kill due to that? 83 boolean setIsForeground; // Running foreground UI when last set? 84 boolean hasActivities; // Are there any activities running in this process? 85 boolean hasClientActivities; // Are there any client services with activities? 86 boolean hasStartedServices; // Are there any started services running in this process? 87 boolean foregroundServices; // Running any services that are foreground? 88 boolean foregroundActivities; // Running any activities that are foreground? 89 boolean systemNoUi; // This is a system process, but not currently showing UI. 90 boolean hasShownUi; // Has UI been shown in this process since it was started? 91 boolean pendingUiClean; // Want to clean up resources from showing UI? 92 boolean hasAboveClient; // Bound using BIND_ABOVE_CLIENT, so want to be lower 93 boolean bad; // True if disabled in the bad process list 94 boolean killedBackground; // True when proc has been killed due to too many bg 95 boolean procStateChanged; // Keep track of whether we changed 'setAdj'. 96 String waitingToKill; // Process is waiting to be killed when in the bg; reason 97 IBinder forcingToForeground;// Token that is forcing this process to be foreground 98 int adjSeq; // Sequence id for identifying oom_adj assignment cycles 99 int lruSeq; // Sequence id for identifying LRU update cycles 100 CompatibilityInfo compat; // last used compatibility mode 101 IBinder.DeathRecipient deathRecipient; // Who is watching for the death. 102 ComponentName instrumentationClass;// class installed to instrument app 103 ApplicationInfo instrumentationInfo; // the application being instrumented 104 String instrumentationProfileFile; // where to save profiling 105 IInstrumentationWatcher instrumentationWatcher; // who is waiting 106 IUiAutomationConnection instrumentationUiAutomationConnection; // Connection to use the UI introspection APIs. 107 Bundle instrumentationArguments;// as given to us 108 ComponentName instrumentationResultClass;// copy of instrumentationClass 109 boolean usingWrapper; // Set to true when process was launched with a wrapper attached 110 BroadcastRecord curReceiver;// receiver currently running in the app 111 long lastWakeTime; // How long proc held wake lock at last check 112 long lastCpuTime; // How long proc has run CPU at last check 113 long curCpuTime; // How long proc has run CPU most recently 114 long lastRequestedGc; // When we last asked the app to do a gc 115 long lastLowMemory; // When we last told the app that memory is low 116 boolean reportLowMemory; // Set to true when waiting to report low mem 117 boolean empty; // Is this an empty background process? 118 boolean cached; // Is this a cached process? 119 String adjType; // Debugging: primary thing impacting oom_adj. 120 int adjTypeCode; // Debugging: adj code to report to app. 121 Object adjSource; // Debugging: option dependent object. 122 int adjSourceOom; // Debugging: oom_adj of adjSource's process. 123 Object adjTarget; // Debugging: target component impacting oom_adj. 124 125 // contains HistoryRecord objects 126 final ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>(); 127 // all ServiceRecord running in this process 128 final ArraySet<ServiceRecord> services = new ArraySet<ServiceRecord>(); 129 // services that are currently executing code (need to remain foreground). 130 final ArraySet<ServiceRecord> executingServices 131 = new ArraySet<ServiceRecord>(); 132 // All ConnectionRecord this process holds 133 final ArraySet<ConnectionRecord> connections 134 = new ArraySet<ConnectionRecord>(); 135 // all IIntentReceivers that are registered from this process. 136 final ArraySet<ReceiverList> receivers = new ArraySet<ReceiverList>(); 137 // class (String) -> ContentProviderRecord 138 final ArrayMap<String, ContentProviderRecord> pubProviders 139 = new ArrayMap<String, ContentProviderRecord>(); 140 // All ContentProviderRecord process is using 141 final ArrayList<ContentProviderConnection> conProviders 142 = new ArrayList<ContentProviderConnection>(); 143 144 boolean execServicesFg; // do we need to be executing services in the foreground? 145 boolean persistent; // always keep this application running? 146 boolean crashing; // are we in the process of crashing? 147 Dialog crashDialog; // dialog being displayed due to crash. 148 boolean forceCrashReport; // suppress normal auto-dismiss of crash dialog & report UI? 149 boolean notResponding; // does the app have a not responding dialog? 150 Dialog anrDialog; // dialog being displayed due to app not resp. 151 boolean removed; // has app package been removed from device? 152 boolean debugging; // was app launched for debugging? 153 boolean waitedForDebugger; // has process show wait for debugger dialog? 154 Dialog waitDialog; // current wait for debugger dialog 155 156 String shortStringName; // caching of toShortString() result. 157 String stringName; // caching of toString() result. 158 159 // These reports are generated & stored when an app gets into an error condition. 160 // They will be "null" when all is OK. 161 ActivityManager.ProcessErrorStateInfo crashingReport; 162 ActivityManager.ProcessErrorStateInfo notRespondingReport; 163 164 // Who will be notified of the error. This is usually an activity in the 165 // app that installed the package. 166 ComponentName errorReportReceiver; 167 168 void dump(PrintWriter pw, String prefix) { 169 final long now = SystemClock.uptimeMillis(); 170 171 pw.print(prefix); pw.print("user #"); pw.print(userId); 172 pw.print(" uid="); pw.print(info.uid); 173 if (uid != info.uid) { 174 pw.print(" ISOLATED uid="); pw.print(uid); 175 } 176 pw.println(); 177 if (info.className != null) { 178 pw.print(prefix); pw.print("class="); pw.println(info.className); 179 } 180 if (info.manageSpaceActivityName != null) { 181 pw.print(prefix); pw.print("manageSpaceActivityName="); 182 pw.println(info.manageSpaceActivityName); 183 } 184 pw.print(prefix); pw.print("dir="); pw.print(info.sourceDir); 185 pw.print(" publicDir="); pw.print(info.publicSourceDir); 186 pw.print(" data="); pw.println(info.dataDir); 187 pw.print(prefix); pw.print("packageList={"); 188 for (int i=0; i<pkgList.size(); i++) { 189 if (i > 0) pw.print(", "); 190 pw.print(pkgList.keyAt(i)); 191 } 192 pw.println("}"); 193 pw.print(prefix); pw.print("compat="); pw.println(compat); 194 if (instrumentationClass != null || instrumentationProfileFile != null 195 || instrumentationArguments != null) { 196 pw.print(prefix); pw.print("instrumentationClass="); 197 pw.print(instrumentationClass); 198 pw.print(" instrumentationProfileFile="); 199 pw.println(instrumentationProfileFile); 200 pw.print(prefix); pw.print("instrumentationArguments="); 201 pw.println(instrumentationArguments); 202 pw.print(prefix); pw.print("instrumentationInfo="); 203 pw.println(instrumentationInfo); 204 if (instrumentationInfo != null) { 205 instrumentationInfo.dump(new PrintWriterPrinter(pw), prefix + " "); 206 } 207 } 208 pw.print(prefix); pw.print("thread="); pw.println(thread); 209 pw.print(prefix); pw.print("pid="); pw.print(pid); pw.print(" starting="); 210 pw.println(starting); 211 pw.print(prefix); pw.print("lastActivityTime="); 212 TimeUtils.formatDuration(lastActivityTime, now, pw); 213 pw.print(" lruWeight="); pw.println(lruWeight); 214 pw.print(prefix); pw.print("serviceb="); pw.print(serviceb); 215 pw.print(" keeping="); pw.print(keeping); 216 pw.print(" cached="); pw.print(cached); 217 pw.print(" empty="); pw.println(empty); 218 pw.print(prefix); pw.print("oom: max="); pw.print(maxAdj); 219 pw.print(" curRaw="); pw.print(curRawAdj); 220 pw.print(" setRaw="); pw.print(setRawAdj); 221 pw.print(" cur="); pw.print(curAdj); 222 pw.print(" set="); pw.println(setAdj); 223 pw.print(prefix); pw.print("curSchedGroup="); pw.print(curSchedGroup); 224 pw.print(" setSchedGroup="); pw.print(setSchedGroup); 225 pw.print(" systemNoUi="); pw.print(systemNoUi); 226 pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel); 227 pw.print(prefix); pw.print("curProcState="); pw.print(curProcState); 228 pw.print(" repProcState="); pw.print(repProcState); 229 pw.print(" pssProcState="); pw.print(pssProcState); 230 pw.print(" setProcState="); pw.print(setProcState); 231 pw.print(" lastStateTime="); 232 TimeUtils.formatDuration(lastStateTime, now, pw); 233 pw.println(); 234 pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq); 235 pw.print(" lruSeq="); pw.print(lruSeq); 236 pw.print(" lastPssTime="); 237 TimeUtils.formatDuration(lastPssTime, now, pw); 238 pw.print(" nextPssTime="); 239 TimeUtils.formatDuration(nextPssTime, now, pw); 240 pw.println(); 241 if (hasShownUi || pendingUiClean || hasAboveClient) { 242 pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi); 243 pw.print(" pendingUiClean="); pw.print(pendingUiClean); 244 pw.print(" hasAboveClient="); pw.println(hasAboveClient); 245 } 246 if (setIsForeground || foregroundServices || forcingToForeground != null) { 247 pw.print(prefix); pw.print("setIsForeground="); pw.print(setIsForeground); 248 pw.print(" foregroundServices="); pw.print(foregroundServices); 249 pw.print(" forcingToForeground="); pw.println(forcingToForeground); 250 } 251 if (persistent || removed) { 252 pw.print(prefix); pw.print("persistent="); pw.print(persistent); 253 pw.print(" removed="); pw.println(removed); 254 } 255 if (hasActivities || hasClientActivities || foregroundActivities) { 256 pw.print(prefix); pw.print("hasActivities="); pw.print(hasActivities); 257 pw.print(" hasClientActivities="); pw.print(hasClientActivities); 258 pw.print(" foregroundActivities="); pw.println(foregroundActivities); 259 } 260 if (hasStartedServices) { 261 pw.print(prefix); pw.print("hasStartedServices="); pw.println(hasStartedServices); 262 } 263 if (!keeping) { 264 long wtime; 265 synchronized (batteryStats.getBatteryStats()) { 266 wtime = batteryStats.getBatteryStats().getProcessWakeTime(info.uid, 267 pid, SystemClock.elapsedRealtime()); 268 } 269 long timeUsed = wtime - lastWakeTime; 270 pw.print(prefix); pw.print("lastWakeTime="); pw.print(lastWakeTime); 271 pw.print(" timeUsed="); 272 TimeUtils.formatDuration(timeUsed, pw); pw.println(""); 273 pw.print(prefix); pw.print("lastCpuTime="); pw.print(lastCpuTime); 274 pw.print(" timeUsed="); 275 TimeUtils.formatDuration(curCpuTime-lastCpuTime, pw); pw.println(""); 276 } 277 pw.print(prefix); pw.print("lastRequestedGc="); 278 TimeUtils.formatDuration(lastRequestedGc, now, pw); 279 pw.print(" lastLowMemory="); 280 TimeUtils.formatDuration(lastLowMemory, now, pw); 281 pw.print(" reportLowMemory="); pw.println(reportLowMemory); 282 if (killedBackground || waitingToKill != null) { 283 pw.print(prefix); pw.print("killedBackground="); pw.print(killedBackground); 284 pw.print(" waitingToKill="); pw.println(waitingToKill); 285 } 286 if (debugging || crashing || crashDialog != null || notResponding 287 || anrDialog != null || bad) { 288 pw.print(prefix); pw.print("debugging="); pw.print(debugging); 289 pw.print(" crashing="); pw.print(crashing); 290 pw.print(" "); pw.print(crashDialog); 291 pw.print(" notResponding="); pw.print(notResponding); 292 pw.print(" " ); pw.print(anrDialog); 293 pw.print(" bad="); pw.print(bad); 294 295 // crashing or notResponding is always set before errorReportReceiver 296 if (errorReportReceiver != null) { 297 pw.print(" errorReportReceiver="); 298 pw.print(errorReportReceiver.flattenToShortString()); 299 } 300 pw.println(); 301 } 302 if (activities.size() > 0) { 303 pw.print(prefix); pw.println("Activities:"); 304 for (int i=0; i<activities.size(); i++) { 305 pw.print(prefix); pw.print(" - "); pw.println(activities.get(i)); 306 } 307 } 308 if (services.size() > 0) { 309 pw.print(prefix); pw.println("Services:"); 310 for (int i=0; i<services.size(); i++) { 311 pw.print(prefix); pw.print(" - "); pw.println(services.valueAt(i)); 312 } 313 } 314 if (executingServices.size() > 0) { 315 pw.print(prefix); pw.print("Executing Services (fg="); 316 pw.print(execServicesFg); pw.println(")"); 317 for (int i=0; i<executingServices.size(); i++) { 318 pw.print(prefix); pw.print(" - "); pw.println(executingServices.valueAt(i)); 319 } 320 } 321 if (connections.size() > 0) { 322 pw.print(prefix); pw.println("Connections:"); 323 for (int i=0; i<connections.size(); i++) { 324 pw.print(prefix); pw.print(" - "); pw.println(connections.valueAt(i)); 325 } 326 } 327 if (pubProviders.size() > 0) { 328 pw.print(prefix); pw.println("Published Providers:"); 329 for (int i=0; i<pubProviders.size(); i++) { 330 pw.print(prefix); pw.print(" - "); pw.println(pubProviders.keyAt(i)); 331 pw.print(prefix); pw.print(" -> "); pw.println(pubProviders.valueAt(i)); 332 } 333 } 334 if (conProviders.size() > 0) { 335 pw.print(prefix); pw.println("Connected Providers:"); 336 for (int i=0; i<conProviders.size(); i++) { 337 pw.print(prefix); pw.print(" - "); pw.println(conProviders.get(i).toShortString()); 338 } 339 } 340 if (curReceiver != null) { 341 pw.print(prefix); pw.print("curReceiver="); pw.println(curReceiver); 342 } 343 if (receivers.size() > 0) { 344 pw.print(prefix); pw.println("Receivers:"); 345 for (int i=0; i<receivers.size(); i++) { 346 pw.print(prefix); pw.print(" - "); pw.println(receivers.valueAt(i)); 347 } 348 } 349 } 350 351 ProcessRecord(BatteryStatsImpl.Uid.Proc _batteryStats, IApplicationThread _thread, 352 ApplicationInfo _info, String _processName, int _uid, 353 ProcessTracker.ProcessState tracker) { 354 batteryStats = _batteryStats; 355 info = _info; 356 isolated = _info.uid != _uid; 357 uid = _uid; 358 userId = UserHandle.getUserId(_uid); 359 processName = _processName; 360 baseProcessTracker = tracker; 361 pkgList.put(_info.packageName, tracker); 362 thread = _thread; 363 maxAdj = ProcessList.UNKNOWN_ADJ; 364 curRawAdj = setRawAdj = -100; 365 curAdj = setAdj = -100; 366 persistent = false; 367 removed = false; 368 lastStateTime = lastPssTime = nextPssTime = SystemClock.uptimeMillis(); 369 } 370 371 public void setPid(int _pid) { 372 pid = _pid; 373 shortStringName = null; 374 stringName = null; 375 } 376 377 /** 378 * This method returns true if any of the activities within the process record are interesting 379 * to the user. See HistoryRecord.isInterestingToUserLocked() 380 */ 381 public boolean isInterestingToUserLocked() { 382 final int size = activities.size(); 383 for (int i = 0 ; i < size ; i++) { 384 ActivityRecord r = activities.get(i); 385 if (r.isInterestingToUserLocked()) { 386 return true; 387 } 388 } 389 return false; 390 } 391 392 public void stopFreezingAllLocked() { 393 int i = activities.size(); 394 while (i > 0) { 395 i--; 396 activities.get(i).stopFreezingScreenLocked(true); 397 } 398 } 399 400 public void unlinkDeathRecipient() { 401 if (deathRecipient != null && thread != null) { 402 thread.asBinder().unlinkToDeath(deathRecipient, 0); 403 } 404 deathRecipient = null; 405 } 406 407 void updateHasAboveClientLocked() { 408 hasAboveClient = false; 409 for (int i=connections.size()-1; i>=0; i--) { 410 ConnectionRecord cr = connections.valueAt(i); 411 if ((cr.flags&Context.BIND_ABOVE_CLIENT) != 0) { 412 hasAboveClient = true; 413 break; 414 } 415 } 416 } 417 418 int modifyRawOomAdj(int adj) { 419 if (hasAboveClient) { 420 // If this process has bound to any services with BIND_ABOVE_CLIENT, 421 // then we need to drop its adjustment to be lower than the service's 422 // in order to honor the request. We want to drop it by one adjustment 423 // level... but there is special meaning applied to various levels so 424 // we will skip some of them. 425 if (adj < ProcessList.FOREGROUND_APP_ADJ) { 426 // System process will not get dropped, ever 427 } else if (adj < ProcessList.VISIBLE_APP_ADJ) { 428 adj = ProcessList.VISIBLE_APP_ADJ; 429 } else if (adj < ProcessList.PERCEPTIBLE_APP_ADJ) { 430 adj = ProcessList.PERCEPTIBLE_APP_ADJ; 431 } else if (adj < ProcessList.CACHED_APP_MIN_ADJ) { 432 adj = ProcessList.CACHED_APP_MIN_ADJ; 433 } else if (adj < ProcessList.CACHED_APP_MAX_ADJ) { 434 adj++; 435 } 436 } 437 return adj; 438 } 439 440 public String toShortString() { 441 if (shortStringName != null) { 442 return shortStringName; 443 } 444 StringBuilder sb = new StringBuilder(128); 445 toShortString(sb); 446 return shortStringName = sb.toString(); 447 } 448 449 void toShortString(StringBuilder sb) { 450 sb.append(pid); 451 sb.append(':'); 452 sb.append(processName); 453 sb.append('/'); 454 if (info.uid < Process.FIRST_APPLICATION_UID) { 455 sb.append(uid); 456 } else { 457 sb.append('u'); 458 sb.append(userId); 459 int appId = UserHandle.getAppId(info.uid); 460 if (appId >= Process.FIRST_APPLICATION_UID) { 461 sb.append('a'); 462 sb.append(appId - Process.FIRST_APPLICATION_UID); 463 } else { 464 sb.append('s'); 465 sb.append(appId); 466 } 467 if (uid != info.uid) { 468 sb.append('i'); 469 sb.append(UserHandle.getAppId(uid) - Process.FIRST_ISOLATED_UID); 470 } 471 } 472 } 473 474 public String toString() { 475 if (stringName != null) { 476 return stringName; 477 } 478 StringBuilder sb = new StringBuilder(128); 479 sb.append("ProcessRecord{"); 480 sb.append(Integer.toHexString(System.identityHashCode(this))); 481 sb.append(' '); 482 toShortString(sb); 483 sb.append('}'); 484 return stringName = sb.toString(); 485 } 486 487 /* 488 * Return true if package has been added false if not 489 */ 490 public boolean addPackage(String pkg, ProcessTracker tracker) { 491 if (!pkgList.containsKey(pkg)) { 492 pkgList.put(pkg, tracker.getProcessStateLocked(pkg, info.uid, processName)); 493 return true; 494 } 495 return false; 496 } 497 498 public int getSetAdjWithServices() { 499 if (setAdj >= ProcessList.CACHED_APP_MIN_ADJ) { 500 if (hasStartedServices) { 501 return ProcessList.SERVICE_B_ADJ; 502 } 503 } 504 return setAdj; 505 } 506 507 public void forceProcessStateUpTo(int newState) { 508 if (repProcState > newState) { 509 curProcState = repProcState = newState; 510 } 511 } 512 513 /* 514 * Delete all packages from list except the package indicated in info 515 */ 516 public void resetPackageList(ProcessTracker tracker) { 517 long now = SystemClock.uptimeMillis(); 518 baseProcessTracker.setState(ProcessTracker.STATE_NOTHING, 0, now, pkgList); 519 if (pkgList.size() != 1) { 520 pkgList.clear(); 521 pkgList.put(info.packageName, tracker.getProcessStateLocked( 522 info.packageName, info.uid, processName)); 523 } 524 } 525 526 public String[] getPackageList() { 527 int size = pkgList.size(); 528 if (size == 0) { 529 return null; 530 } 531 String list[] = new String[size]; 532 for (int i=0; i<pkgList.size(); i++) { 533 list[i] = pkgList.keyAt(i); 534 } 535 return list; 536 } 537} 538