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