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