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