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