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 com.android.internal.os.BatteryStatsImpl;
     20 
     21 import android.app.ActivityManager;
     22 import android.app.Dialog;
     23 import android.app.IApplicationThread;
     24 import android.app.IInstrumentationWatcher;
     25 import android.content.ComponentName;
     26 import android.content.Context;
     27 import android.content.pm.ApplicationInfo;
     28 import android.content.res.CompatibilityInfo;
     29 import android.os.Bundle;
     30 import android.os.IBinder;
     31 import android.os.Process;
     32 import android.os.SystemClock;
     33 import android.os.UserId;
     34 import android.util.PrintWriterPrinter;
     35 import android.util.TimeUtils;
     36 
     37 import java.io.PrintWriter;
     38 import java.util.ArrayList;
     39 import java.util.HashMap;
     40 import java.util.HashSet;
     41 
     42 /**
     43  * Full information about a particular process that
     44  * is currently running.
     45  */
     46 class ProcessRecord {
     47     final BatteryStatsImpl.Uid.Proc batteryStats; // where to collect runtime statistics
     48     final ApplicationInfo info; // all about the first app in the process
     49     final boolean isolated;     // true if this is a special isolated process
     50     final int uid;              // uid of process; may be different from 'info' if isolated
     51     final int userId;           // user of process.
     52     final String processName;   // name of the process
     53     // List of packages running in the process
     54     final HashSet<String> pkgList = new HashSet<String>();
     55     IApplicationThread thread;  // the actual proc...  may be null only if
     56                                 // 'persistent' is true (in which case we
     57                                 // are in the process of launching the app)
     58     int pid;                    // The process of this application; 0 if none
     59     boolean starting;           // True if the process is being started
     60     long lastActivityTime;      // For managing the LRU list
     61     long lruWeight;             // Weight for ordering in LRU list
     62     int maxAdj;                 // Maximum OOM adjustment for this process
     63     int hiddenAdj;              // If hidden, this is the adjustment to use
     64     int curRawAdj;              // Current OOM unlimited adjustment for this process
     65     int setRawAdj;              // Last set OOM unlimited adjustment for this process
     66     int nonStoppingAdj;         // Adjustment not counting any stopping activities
     67     int curAdj;                 // Current OOM adjustment for this process
     68     int setAdj;                 // Last set OOM adjustment for this process
     69     int curSchedGroup;          // Currently desired scheduling class
     70     int setSchedGroup;          // Last set to background scheduling class
     71     int trimMemoryLevel;        // Last selected memory trimming level
     72     int memImportance;          // Importance constant computed from curAdj
     73     boolean serviceb;           // Process currently is on the service B list
     74     boolean keeping;            // Actively running code so don't kill due to that?
     75     boolean setIsForeground;    // Running foreground UI when last set?
     76     boolean foregroundServices; // Running any services that are foreground?
     77     boolean foregroundActivities; // Running any activities that are foreground?
     78     boolean systemNoUi;         // This is a system process, but not currently showing UI.
     79     boolean hasShownUi;         // Has UI been shown in this process since it was started?
     80     boolean pendingUiClean;     // Want to clean up resources from showing UI?
     81     boolean hasAboveClient;     // Bound using BIND_ABOVE_CLIENT, so want to be lower
     82     boolean bad;                // True if disabled in the bad process list
     83     boolean killedBackground;   // True when proc has been killed due to too many bg
     84     String waitingToKill;       // Process is waiting to be killed when in the bg; reason
     85     IBinder forcingToForeground;// Token that is forcing this process to be foreground
     86     int adjSeq;                 // Sequence id for identifying oom_adj assignment cycles
     87     int lruSeq;                 // Sequence id for identifying LRU update cycles
     88     CompatibilityInfo compat;   // last used compatibility mode
     89     IBinder.DeathRecipient deathRecipient; // Who is watching for the death.
     90     ComponentName instrumentationClass;// class installed to instrument app
     91     ApplicationInfo instrumentationInfo; // the application being instrumented
     92     String instrumentationProfileFile; // where to save profiling
     93     IInstrumentationWatcher instrumentationWatcher; // who is waiting
     94     Bundle instrumentationArguments;// as given to us
     95     ComponentName instrumentationResultClass;// copy of instrumentationClass
     96     boolean usingWrapper;       // Set to true when process was launched with a wrapper attached
     97     BroadcastRecord curReceiver;// receiver currently running in the app
     98     long lastWakeTime;          // How long proc held wake lock at last check
     99     long lastCpuTime;           // How long proc has run CPU at last check
    100     long curCpuTime;            // How long proc has run CPU most recently
    101     long lastRequestedGc;       // When we last asked the app to do a gc
    102     long lastLowMemory;         // When we last told the app that memory is low
    103     boolean reportLowMemory;    // Set to true when waiting to report low mem
    104     boolean empty;              // Is this an empty background process?
    105     boolean hidden;             // Is this a hidden process?
    106     int lastPss;                // Last pss size reported by app.
    107     String adjType;             // Debugging: primary thing impacting oom_adj.
    108     int adjTypeCode;            // Debugging: adj code to report to app.
    109     Object adjSource;           // Debugging: option dependent object.
    110     int adjSourceOom;           // Debugging: oom_adj of adjSource's process.
    111     Object adjTarget;           // Debugging: target component impacting oom_adj.
    112 
    113     // contains HistoryRecord objects
    114     final ArrayList<ActivityRecord> activities = new ArrayList<ActivityRecord>();
    115     // all ServiceRecord running in this process
    116     final HashSet<ServiceRecord> services = new HashSet<ServiceRecord>();
    117     // services that are currently executing code (need to remain foreground).
    118     final HashSet<ServiceRecord> executingServices
    119              = new HashSet<ServiceRecord>();
    120     // All ConnectionRecord this process holds
    121     final HashSet<ConnectionRecord> connections
    122             = new HashSet<ConnectionRecord>();
    123     // all IIntentReceivers that are registered from this process.
    124     final HashSet<ReceiverList> receivers = new HashSet<ReceiverList>();
    125     // class (String) -> ContentProviderRecord
    126     final HashMap<String, ContentProviderRecord> pubProviders
    127             = new HashMap<String, ContentProviderRecord>();
    128     // All ContentProviderRecord process is using
    129     final ArrayList<ContentProviderConnection> conProviders
    130             = new ArrayList<ContentProviderConnection>();
    131 
    132     boolean persistent;         // always keep this application running?
    133     boolean crashing;           // are we in the process of crashing?
    134     Dialog crashDialog;         // dialog being displayed due to crash.
    135     boolean notResponding;      // does the app have a not responding dialog?
    136     Dialog anrDialog;           // dialog being displayed due to app not resp.
    137     boolean removed;            // has app package been removed from device?
    138     boolean debugging;          // was app launched for debugging?
    139     boolean waitedForDebugger;  // has process show wait for debugger dialog?
    140     Dialog waitDialog;          // current wait for debugger dialog
    141 
    142     String shortStringName;     // caching of toShortString() result.
    143     String stringName;          // caching of toString() result.
    144 
    145     // These reports are generated & stored when an app gets into an error condition.
    146     // They will be "null" when all is OK.
    147     ActivityManager.ProcessErrorStateInfo crashingReport;
    148     ActivityManager.ProcessErrorStateInfo notRespondingReport;
    149 
    150     // Who will be notified of the error. This is usually an activity in the
    151     // app that installed the package.
    152     ComponentName errorReportReceiver;
    153 
    154     void dump(PrintWriter pw, String prefix) {
    155         final long now = SystemClock.uptimeMillis();
    156 
    157         pw.print(prefix); pw.print("user #"); pw.print(userId);
    158                 pw.print(" uid="); pw.print(info.uid);
    159         if (uid != info.uid) {
    160             pw.print(" ISOLATED uid="); pw.print(uid);
    161         }
    162         pw.println();
    163         if (info.className != null) {
    164             pw.print(prefix); pw.print("class="); pw.println(info.className);
    165         }
    166         if (info.manageSpaceActivityName != null) {
    167             pw.print(prefix); pw.print("manageSpaceActivityName=");
    168             pw.println(info.manageSpaceActivityName);
    169         }
    170         pw.print(prefix); pw.print("dir="); pw.print(info.sourceDir);
    171                 pw.print(" publicDir="); pw.print(info.publicSourceDir);
    172                 pw.print(" data="); pw.println(info.dataDir);
    173         pw.print(prefix); pw.print("packageList="); pw.println(pkgList);
    174         pw.print(prefix); pw.print("compat="); pw.println(compat);
    175         if (instrumentationClass != null || instrumentationProfileFile != null
    176                 || instrumentationArguments != null) {
    177             pw.print(prefix); pw.print("instrumentationClass=");
    178                     pw.print(instrumentationClass);
    179                     pw.print(" instrumentationProfileFile=");
    180                     pw.println(instrumentationProfileFile);
    181             pw.print(prefix); pw.print("instrumentationArguments=");
    182                     pw.println(instrumentationArguments);
    183             pw.print(prefix); pw.print("instrumentationInfo=");
    184                     pw.println(instrumentationInfo);
    185             if (instrumentationInfo != null) {
    186                 instrumentationInfo.dump(new PrintWriterPrinter(pw), prefix + "  ");
    187             }
    188         }
    189         pw.print(prefix); pw.print("thread="); pw.print(thread);
    190                 pw.print(" curReceiver="); pw.println(curReceiver);
    191         pw.print(prefix); pw.print("pid="); pw.print(pid); pw.print(" starting=");
    192                 pw.print(starting); pw.print(" lastPss="); pw.println(lastPss);
    193         pw.print(prefix); pw.print("lastActivityTime=");
    194                 TimeUtils.formatDuration(lastActivityTime, now, pw);
    195                 pw.print(" lruWeight="); pw.print(lruWeight);
    196                 pw.print(" serviceb="); pw.print(serviceb);
    197                 pw.print(" keeping="); pw.print(keeping);
    198                 pw.print(" hidden="); pw.print(hidden);
    199                 pw.print(" empty="); pw.println(empty);
    200         pw.print(prefix); pw.print("oom: max="); pw.print(maxAdj);
    201                 pw.print(" hidden="); pw.print(hiddenAdj);
    202                 pw.print(" curRaw="); pw.print(curRawAdj);
    203                 pw.print(" setRaw="); pw.print(setRawAdj);
    204                 pw.print(" nonStopping="); pw.print(nonStoppingAdj);
    205                 pw.print(" cur="); pw.print(curAdj);
    206                 pw.print(" set="); pw.println(setAdj);
    207         pw.print(prefix); pw.print("curSchedGroup="); pw.print(curSchedGroup);
    208                 pw.print(" setSchedGroup="); pw.print(setSchedGroup);
    209                 pw.print(" systemNoUi="); pw.print(systemNoUi);
    210                 pw.print(" trimMemoryLevel="); pw.println(trimMemoryLevel);
    211         pw.print(prefix); pw.print("hasShownUi="); pw.print(hasShownUi);
    212                 pw.print(" pendingUiClean="); pw.print(pendingUiClean);
    213                 pw.print(" hasAboveClient="); pw.println(hasAboveClient);
    214         pw.print(prefix); pw.print("setIsForeground="); pw.print(setIsForeground);
    215                 pw.print(" foregroundServices="); pw.print(foregroundServices);
    216                 pw.print(" forcingToForeground="); pw.println(forcingToForeground);
    217         pw.print(prefix); pw.print("persistent="); pw.print(persistent);
    218                 pw.print(" removed="); pw.println(removed);
    219         pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq);
    220                 pw.print(" lruSeq="); pw.println(lruSeq);
    221         if (!keeping) {
    222             long wtime;
    223             synchronized (batteryStats.getBatteryStats()) {
    224                 wtime = batteryStats.getBatteryStats().getProcessWakeTime(info.uid,
    225                         pid, SystemClock.elapsedRealtime());
    226             }
    227             long timeUsed = wtime - lastWakeTime;
    228             pw.print(prefix); pw.print("lastWakeTime="); pw.print(lastWakeTime);
    229                     pw.print(" time used=");
    230                     TimeUtils.formatDuration(timeUsed, pw); pw.println("");
    231             pw.print(prefix); pw.print("lastCpuTime="); pw.print(lastCpuTime);
    232                     pw.print(" time used=");
    233                     TimeUtils.formatDuration(curCpuTime-lastCpuTime, pw); pw.println("");
    234         }
    235         pw.print(prefix); pw.print("lastRequestedGc=");
    236                 TimeUtils.formatDuration(lastRequestedGc, now, pw);
    237                 pw.print(" lastLowMemory=");
    238                 TimeUtils.formatDuration(lastLowMemory, now, pw);
    239                 pw.print(" reportLowMemory="); pw.println(reportLowMemory);
    240         if (killedBackground || waitingToKill != null) {
    241             pw.print(prefix); pw.print("killedBackground="); pw.print(killedBackground);
    242                     pw.print(" waitingToKill="); pw.println(waitingToKill);
    243         }
    244         if (debugging || crashing || crashDialog != null || notResponding
    245                 || anrDialog != null || bad) {
    246             pw.print(prefix); pw.print("debugging="); pw.print(debugging);
    247                     pw.print(" crashing="); pw.print(crashing);
    248                     pw.print(" "); pw.print(crashDialog);
    249                     pw.print(" notResponding="); pw.print(notResponding);
    250                     pw.print(" " ); pw.print(anrDialog);
    251                     pw.print(" bad="); pw.print(bad);
    252 
    253                     // crashing or notResponding is always set before errorReportReceiver
    254                     if (errorReportReceiver != null) {
    255                         pw.print(" errorReportReceiver=");
    256                         pw.print(errorReportReceiver.flattenToShortString());
    257                     }
    258                     pw.println();
    259         }
    260         if (activities.size() > 0) {
    261             pw.print(prefix); pw.println("Activities:");
    262             for (int i=0; i<activities.size(); i++) {
    263                 pw.print(prefix); pw.print("  - "); pw.println(activities.get(i));
    264             }
    265         }
    266         if (services.size() > 0) {
    267             pw.print(prefix); pw.println("Services:");
    268             for (ServiceRecord sr : services) {
    269                 pw.print(prefix); pw.print("  - "); pw.println(sr);
    270             }
    271         }
    272         if (executingServices.size() > 0) {
    273             pw.print(prefix); pw.println("Executing Services:");
    274             for (ServiceRecord sr : executingServices) {
    275                 pw.print(prefix); pw.print("  - "); pw.println(sr);
    276             }
    277         }
    278         if (connections.size() > 0) {
    279             pw.print(prefix); pw.println("Connections:");
    280             for (ConnectionRecord cr : connections) {
    281                 pw.print(prefix); pw.print("  - "); pw.println(cr);
    282             }
    283         }
    284         if (pubProviders.size() > 0) {
    285             pw.print(prefix); pw.println("Published Providers:");
    286             for (HashMap.Entry<String, ContentProviderRecord> ent : pubProviders.entrySet()) {
    287                 pw.print(prefix); pw.print("  - "); pw.println(ent.getKey());
    288                 pw.print(prefix); pw.print("    -> "); pw.println(ent.getValue());
    289             }
    290         }
    291         if (conProviders.size() > 0) {
    292             pw.print(prefix); pw.println("Connected Providers:");
    293             for (int i=0; i<conProviders.size(); i++) {
    294                 pw.print(prefix); pw.print("  - "); pw.println(conProviders.get(i).toShortString());
    295             }
    296         }
    297         if (receivers.size() > 0) {
    298             pw.print(prefix); pw.println("Receivers:");
    299             for (ReceiverList rl : receivers) {
    300                 pw.print(prefix); pw.print("  - "); pw.println(rl);
    301             }
    302         }
    303     }
    304 
    305     ProcessRecord(BatteryStatsImpl.Uid.Proc _batteryStats, IApplicationThread _thread,
    306             ApplicationInfo _info, String _processName, int _uid) {
    307         batteryStats = _batteryStats;
    308         info = _info;
    309         isolated = _info.uid != _uid;
    310         uid = _uid;
    311         userId = UserId.getUserId(_uid);
    312         processName = _processName;
    313         pkgList.add(_info.packageName);
    314         thread = _thread;
    315         maxAdj = ProcessList.HIDDEN_APP_MAX_ADJ;
    316         hiddenAdj = ProcessList.HIDDEN_APP_MIN_ADJ;
    317         curRawAdj = setRawAdj = -100;
    318         curAdj = setAdj = -100;
    319         persistent = false;
    320         removed = false;
    321     }
    322 
    323     public void setPid(int _pid) {
    324         pid = _pid;
    325         shortStringName = null;
    326         stringName = null;
    327     }
    328 
    329     /**
    330      * This method returns true if any of the activities within the process record are interesting
    331      * to the user. See HistoryRecord.isInterestingToUserLocked()
    332      */
    333     public boolean isInterestingToUserLocked() {
    334         final int size = activities.size();
    335         for (int i = 0 ; i < size ; i++) {
    336             ActivityRecord r = activities.get(i);
    337             if (r.isInterestingToUserLocked()) {
    338                 return true;
    339             }
    340         }
    341         return false;
    342     }
    343 
    344     public void stopFreezingAllLocked() {
    345         int i = activities.size();
    346         while (i > 0) {
    347             i--;
    348             activities.get(i).stopFreezingScreenLocked(true);
    349         }
    350     }
    351 
    352     public void unlinkDeathRecipient() {
    353         if (deathRecipient != null && thread != null) {
    354             thread.asBinder().unlinkToDeath(deathRecipient, 0);
    355         }
    356         deathRecipient = null;
    357     }
    358 
    359     void updateHasAboveClientLocked() {
    360         hasAboveClient = false;
    361         if (connections.size() > 0) {
    362             for (ConnectionRecord cr : connections) {
    363                 if ((cr.flags&Context.BIND_ABOVE_CLIENT) != 0) {
    364                     hasAboveClient = true;
    365                     break;
    366                 }
    367             }
    368         }
    369     }
    370 
    371     public String toShortString() {
    372         if (shortStringName != null) {
    373             return shortStringName;
    374         }
    375         StringBuilder sb = new StringBuilder(128);
    376         toShortString(sb);
    377         return shortStringName = sb.toString();
    378     }
    379 
    380     void toShortString(StringBuilder sb) {
    381         sb.append(pid);
    382         sb.append(':');
    383         sb.append(processName);
    384         sb.append('/');
    385         if (info.uid < Process.FIRST_APPLICATION_UID) {
    386             sb.append(uid);
    387         } else {
    388             sb.append('u');
    389             sb.append(userId);
    390             sb.append('a');
    391             sb.append(info.uid%Process.FIRST_APPLICATION_UID);
    392             if (uid != info.uid) {
    393                 sb.append('i');
    394                 sb.append(UserId.getAppId(uid) - Process.FIRST_ISOLATED_UID);
    395             }
    396         }
    397     }
    398 
    399     public String toString() {
    400         if (stringName != null) {
    401             return stringName;
    402         }
    403         StringBuilder sb = new StringBuilder(128);
    404         sb.append("ProcessRecord{");
    405         sb.append(Integer.toHexString(System.identityHashCode(this)));
    406         sb.append(' ');
    407         toShortString(sb);
    408         sb.append('}');
    409         return stringName = sb.toString();
    410     }
    411 
    412     /*
    413      *  Return true if package has been added false if not
    414      */
    415     public boolean addPackage(String pkg) {
    416         if (!pkgList.contains(pkg)) {
    417             pkgList.add(pkg);
    418             return true;
    419         }
    420         return false;
    421     }
    422 
    423     /*
    424      *  Delete all packages from list except the package indicated in info
    425      */
    426     public void resetPackageList() {
    427         pkgList.clear();
    428         pkgList.add(info.packageName);
    429     }
    430 
    431     public String[] getPackageList() {
    432         int size = pkgList.size();
    433         if (size == 0) {
    434             return null;
    435         }
    436         String list[] = new String[size];
    437         pkgList.toArray(list);
    438         return list;
    439     }
    440 }
    441