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