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