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     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 
    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 
    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 
    407     public void setPid(int _pid) {
    408         pid = _pid;
    409         shortStringName = null;
    410         stringName = null;
    411     }
    412 
    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 
    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      */
    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 
    474     public void stopFreezingAllLocked() {
    475         int i = activities.size();
    476         while (i > 0) {
    477             i--;
    478             activities.get(i).stopFreezingScreenLocked(true);
    479         }
    480     }
    481 
    482     public void unlinkDeathRecipient() {
    483         if (deathRecipient != null && thread != null) {
    484             thread.asBinder().unlinkToDeath(deathRecipient, 0);
    485         }
    486         deathRecipient = null;
    487     }
    488 
    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 
    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 
    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 
    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 
    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 
    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 
    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      */
    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 
    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 
    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      */
    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 
    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