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