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