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 import com.android.server.Watchdog;
     21 
     22 import android.app.ActivityManager;
     23 import android.app.Dialog;
     24 import android.app.IApplicationThread;
     25 import android.app.IInstrumentationWatcher;
     26 import android.content.ComponentName;
     27 import android.content.pm.ApplicationInfo;
     28 import android.os.Bundle;
     29 import android.os.IBinder;
     30 import android.os.RemoteException;
     31 import android.os.SystemClock;
     32 import android.util.PrintWriterPrinter;
     33 
     34 import java.io.PrintWriter;
     35 import java.util.ArrayList;
     36 import java.util.HashMap;
     37 import java.util.HashSet;
     38 
     39 /**
     40  * Full information about a particular process that
     41  * is currently running.
     42  */
     43 class ProcessRecord implements Watchdog.PssRequestor {
     44     final BatteryStatsImpl.Uid.Proc batteryStats; // where to collect runtime statistics
     45     final ApplicationInfo info; // all about the first app in the process
     46     final String processName;   // name of the process
     47     // List of packages running in the process
     48     final HashSet<String> pkgList = new HashSet();
     49     IApplicationThread thread;  // the actual proc...  may be null only if
     50                                 // 'persistent' is true (in which case we
     51                                 // are in the process of launching the app)
     52     int pid;                    // The process of this application; 0 if none
     53     boolean starting;           // True if the process is being started
     54     long lastActivityTime;      // For managing the LRU list
     55     long lruWeight;             // Weight for ordering in LRU list
     56     int maxAdj;                 // Maximum OOM adjustment for this process
     57     int hiddenAdj;              // If hidden, this is the adjustment to use
     58     int curRawAdj;              // Current OOM unlimited adjustment for this process
     59     int setRawAdj;              // Last set OOM unlimited adjustment for this process
     60     int curAdj;                 // Current OOM adjustment for this process
     61     int setAdj;                 // Last set OOM adjustment for this process
     62     int curSchedGroup;          // Currently desired scheduling class
     63     int setSchedGroup;          // Last set to background scheduling class
     64     boolean setIsForeground;    // Running foreground UI when last set?
     65     boolean foregroundServices; // Running any services that are foreground?
     66     boolean bad;                // True if disabled in the bad process list
     67     boolean killedBackground;   // True when proc has been killed due to too many bg
     68     IBinder forcingToForeground;// Token that is forcing this process to be foreground
     69     int adjSeq;                 // Sequence id for identifying oom_adj assignment cycles
     70     int lruSeq;                 // Sequence id for identifying LRU update cycles
     71     ComponentName instrumentationClass;// class installed to instrument app
     72     ApplicationInfo instrumentationInfo; // the application being instrumented
     73     String instrumentationProfileFile; // where to save profiling
     74     IInstrumentationWatcher instrumentationWatcher; // who is waiting
     75     Bundle instrumentationArguments;// as given to us
     76     ComponentName instrumentationResultClass;// copy of instrumentationClass
     77     BroadcastRecord curReceiver;// receiver currently running in the app
     78     long lastRequestedGc;       // When we last asked the app to do a gc
     79     long lastLowMemory;         // When we last told the app that memory is low
     80     boolean reportLowMemory;    // Set to true when waiting to report low mem
     81     boolean empty;              // Is this an empty background process?
     82     boolean hidden;             // Is this a hidden process?
     83     int lastPss;                // Last pss size reported by app.
     84     String adjType;             // Debugging: primary thing impacting oom_adj.
     85     int adjTypeCode;            // Debugging: adj code to report to app.
     86     Object adjSource;           // Debugging: option dependent object.
     87     Object adjTarget;           // Debugging: target component impacting oom_adj.
     88 
     89     // contains HistoryRecord objects
     90     final ArrayList activities = new ArrayList();
     91     // all ServiceRecord running in this process
     92     final HashSet services = new HashSet();
     93     // services that are currently executing code (need to remain foreground).
     94     final HashSet<ServiceRecord> executingServices
     95              = new HashSet<ServiceRecord>();
     96     // All ConnectionRecord this process holds
     97     final HashSet<ConnectionRecord> connections
     98             = new HashSet<ConnectionRecord>();
     99     // all IIntentReceivers that are registered from this process.
    100     final HashSet<ReceiverList> receivers = new HashSet<ReceiverList>();
    101     // class (String) -> ContentProviderRecord
    102     final HashMap pubProviders = new HashMap();
    103     // All ContentProviderRecord process is using
    104     final HashMap<ContentProviderRecord, Integer> conProviders
    105             = new HashMap<ContentProviderRecord, Integer>();
    106 
    107     boolean persistent;         // always keep this application running?
    108     boolean crashing;           // are we in the process of crashing?
    109     Dialog crashDialog;         // dialog being displayed due to crash.
    110     boolean notResponding;      // does the app have a not responding dialog?
    111     Dialog anrDialog;           // dialog being displayed due to app not resp.
    112     boolean removed;            // has app package been removed from device?
    113     boolean debugging;          // was app launched for debugging?
    114     int persistentActivities;   // number of activities that are persistent
    115     boolean waitedForDebugger;  // has process show wait for debugger dialog?
    116     Dialog waitDialog;          // current wait for debugger dialog
    117 
    118     String shortStringName;     // caching of toShortString() result.
    119     String stringName;          // caching of toString() result.
    120 
    121     // These reports are generated & stored when an app gets into an error condition.
    122     // They will be "null" when all is OK.
    123     ActivityManager.ProcessErrorStateInfo crashingReport;
    124     ActivityManager.ProcessErrorStateInfo notRespondingReport;
    125 
    126     // Who will be notified of the error. This is usually an activity in the
    127     // app that installed the package.
    128     ComponentName errorReportReceiver;
    129 
    130     void dump(PrintWriter pw, String prefix) {
    131         long now = SystemClock.uptimeMillis();
    132         if (info.className != null) {
    133             pw.print(prefix); pw.print("class="); pw.println(info.className);
    134         }
    135         if (info.manageSpaceActivityName != null) {
    136             pw.print(prefix); pw.print("manageSpaceActivityName=");
    137             pw.println(info.manageSpaceActivityName);
    138         }
    139         pw.print(prefix); pw.print("dir="); pw.print(info.sourceDir);
    140                 pw.print(" publicDir="); pw.print(info.publicSourceDir);
    141                 pw.print(" data="); pw.println(info.dataDir);
    142         pw.print(prefix); pw.print("packageList="); pw.println(pkgList);
    143         if (instrumentationClass != null || instrumentationProfileFile != null
    144                 || instrumentationArguments != null) {
    145             pw.print(prefix); pw.print("instrumentationClass=");
    146                     pw.print(instrumentationClass);
    147                     pw.print(" instrumentationProfileFile=");
    148                     pw.println(instrumentationProfileFile);
    149             pw.print(prefix); pw.print("instrumentationArguments=");
    150                     pw.println(instrumentationArguments);
    151             pw.print(prefix); pw.print("instrumentationInfo=");
    152                     pw.println(instrumentationInfo);
    153             if (instrumentationInfo != null) {
    154                 instrumentationInfo.dump(new PrintWriterPrinter(pw), prefix + "  ");
    155             }
    156         }
    157         pw.print(prefix); pw.print("thread="); pw.print(thread);
    158                 pw.print(" curReceiver="); pw.println(curReceiver);
    159         pw.print(prefix); pw.print("pid="); pw.print(pid); pw.print(" starting=");
    160                 pw.print(starting); pw.print(" lastPss="); pw.println(lastPss);
    161         pw.print(prefix); pw.print("lastActivityTime="); pw.print(lastActivityTime);
    162                 pw.print(" lruWeight="); pw.println(lruWeight);
    163                 pw.print(" hidden="); pw.print(hidden);
    164                 pw.print(" empty="); pw.println(empty);
    165         pw.print(prefix); pw.print("oom: max="); pw.print(maxAdj);
    166                 pw.print(" hidden="); pw.print(hiddenAdj);
    167                 pw.print(" curRaw="); pw.print(curRawAdj);
    168                 pw.print(" setRaw="); pw.print(setRawAdj);
    169                 pw.print(" cur="); pw.print(curAdj);
    170                 pw.print(" set="); pw.println(setAdj);
    171         pw.print(prefix); pw.print("curSchedGroup="); pw.print(curSchedGroup);
    172                 pw.print(" setSchedGroup="); pw.println(setSchedGroup);
    173         pw.print(prefix); pw.print("setIsForeground="); pw.print(setIsForeground);
    174                 pw.print(" foregroundServices="); pw.print(foregroundServices);
    175                 pw.print(" forcingToForeground="); pw.println(forcingToForeground);
    176         pw.print(prefix); pw.print("persistent="); pw.print(persistent);
    177                 pw.print(" removed="); pw.print(removed);
    178                 pw.print(" persistentActivities="); pw.println(persistentActivities);
    179         pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq);
    180                 pw.print(" lruSeq="); pw.println(lruSeq);
    181         if (killedBackground) {
    182             pw.print(prefix); pw.print("killedBackground="); pw.println(killedBackground);
    183         }
    184         if (debugging || crashing || crashDialog != null || notResponding
    185                 || anrDialog != null || bad) {
    186             pw.print(prefix); pw.print("debugging="); pw.print(debugging);
    187                     pw.print(" crashing="); pw.print(crashing);
    188                     pw.print(" "); pw.print(crashDialog);
    189                     pw.print(" notResponding="); pw.print(notResponding);
    190                     pw.print(" " ); pw.print(anrDialog);
    191                     pw.print(" bad="); pw.print(bad);
    192 
    193                     // crashing or notResponding is always set before errorReportReceiver
    194                     if (errorReportReceiver != null) {
    195                         pw.print(" errorReportReceiver=");
    196                         pw.print(errorReportReceiver.flattenToShortString());
    197                     }
    198                     pw.println();
    199         }
    200         if (activities.size() > 0) {
    201             pw.print(prefix); pw.print("activities="); pw.println(activities);
    202         }
    203         if (services.size() > 0) {
    204             pw.print(prefix); pw.print("services="); pw.println(services);
    205         }
    206         if (executingServices.size() > 0) {
    207             pw.print(prefix); pw.print("executingServices="); pw.println(executingServices);
    208         }
    209         if (connections.size() > 0) {
    210             pw.print(prefix); pw.print("connections="); pw.println(connections);
    211         }
    212         if (pubProviders.size() > 0) {
    213             pw.print(prefix); pw.print("pubProviders="); pw.println(pubProviders);
    214         }
    215         if (conProviders.size() > 0) {
    216             pw.print(prefix); pw.print("conProviders="); pw.println(conProviders);
    217         }
    218         if (receivers.size() > 0) {
    219             pw.print(prefix); pw.print("receivers="); pw.println(receivers);
    220         }
    221     }
    222 
    223     ProcessRecord(BatteryStatsImpl.Uid.Proc _batteryStats, IApplicationThread _thread,
    224             ApplicationInfo _info, String _processName) {
    225         batteryStats = _batteryStats;
    226         info = _info;
    227         processName = _processName;
    228         pkgList.add(_info.packageName);
    229         thread = _thread;
    230         maxAdj = ActivityManagerService.EMPTY_APP_ADJ;
    231         hiddenAdj = ActivityManagerService.HIDDEN_APP_MIN_ADJ;
    232         curRawAdj = setRawAdj = -100;
    233         curAdj = setAdj = -100;
    234         persistent = false;
    235         removed = false;
    236         persistentActivities = 0;
    237     }
    238 
    239     public void setPid(int _pid) {
    240         pid = _pid;
    241         shortStringName = null;
    242         stringName = null;
    243     }
    244 
    245     /**
    246      * This method returns true if any of the activities within the process record are interesting
    247      * to the user. See HistoryRecord.isInterestingToUserLocked()
    248      */
    249     public boolean isInterestingToUserLocked() {
    250         final int size = activities.size();
    251         for (int i = 0 ; i < size ; i++) {
    252             HistoryRecord r = (HistoryRecord) activities.get(i);
    253             if (r.isInterestingToUserLocked()) {
    254                 return true;
    255             }
    256         }
    257         return false;
    258     }
    259 
    260     public void stopFreezingAllLocked() {
    261         int i = activities.size();
    262         while (i > 0) {
    263             i--;
    264             ((HistoryRecord)activities.get(i)).stopFreezingScreenLocked(true);
    265         }
    266     }
    267 
    268     public void requestPss() {
    269         IApplicationThread localThread = thread;
    270         if (localThread != null) {
    271             try {
    272                 localThread.requestPss();
    273             } catch (RemoteException e) {
    274             }
    275         }
    276     }
    277 
    278     public String toShortString() {
    279         if (shortStringName != null) {
    280             return shortStringName;
    281         }
    282         StringBuilder sb = new StringBuilder(128);
    283         toShortString(sb);
    284         return shortStringName = sb.toString();
    285     }
    286 
    287     void toShortString(StringBuilder sb) {
    288         sb.append(Integer.toHexString(System.identityHashCode(this)));
    289         sb.append(' ');
    290         sb.append(pid);
    291         sb.append(':');
    292         sb.append(processName);
    293         sb.append('/');
    294         sb.append(info.uid);
    295     }
    296 
    297     public String toString() {
    298         if (stringName != null) {
    299             return stringName;
    300         }
    301         StringBuilder sb = new StringBuilder(128);
    302         sb.append("ProcessRecord{");
    303         toShortString(sb);
    304         sb.append('}');
    305         return stringName = sb.toString();
    306     }
    307 
    308     /*
    309      *  Return true if package has been added false if not
    310      */
    311     public boolean addPackage(String pkg) {
    312         if (!pkgList.contains(pkg)) {
    313             pkgList.add(pkg);
    314             return true;
    315         }
    316         return false;
    317     }
    318 
    319     /*
    320      *  Delete all packages from list except the package indicated in info
    321      */
    322     public void resetPackageList() {
    323         pkgList.clear();
    324         pkgList.add(info.packageName);
    325     }
    326 
    327     public String[] getPackageList() {
    328         int size = pkgList.size();
    329         if (size == 0) {
    330             return null;
    331         }
    332         String list[] = new String[size];
    333         pkgList.toArray(list);
    334         return list;
    335     }
    336 }
    337