The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame^] | 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 | |
| 32 | import java.io.PrintWriter; |
| 33 | import java.util.ArrayList; |
| 34 | import java.util.HashMap; |
| 35 | import java.util.HashSet; |
| 36 | |
| 37 | /** |
| 38 | * Full information about a particular process that |
| 39 | * is currently running. |
| 40 | */ |
| 41 | class ProcessRecord implements Watchdog.PssRequestor { |
| 42 | final BatteryStatsImpl.Uid.Proc batteryStats; // where to collect runtime statistics |
| 43 | final ApplicationInfo info; // all about the first app in the process |
| 44 | final String processName; // name of the process |
| 45 | // List of packages running in the process |
| 46 | final HashSet<String> pkgList = new HashSet(); |
| 47 | IApplicationThread thread; // the actual proc... may be null only if |
| 48 | // 'persistent' is true (in which case we |
| 49 | // are in the process of launching the app) |
| 50 | int pid; // The process of this application; 0 if none |
| 51 | boolean starting; // True if the process is being started |
| 52 | int maxAdj; // Maximum OOM adjustment for this process |
| 53 | int hiddenAdj; // If hidden, this is the adjustment to use |
| 54 | int curRawAdj; // Current OOM unlimited adjustment for this process |
| 55 | int setRawAdj; // Last set OOM unlimited adjustment for this process |
| 56 | int curAdj; // Current OOM adjustment for this process |
| 57 | int setAdj; // Last set OOM adjustment for this process |
| 58 | boolean isForeground; // Is this app running the foreground UI? |
| 59 | boolean setIsForeground; // Running foreground UI when last set? |
| 60 | boolean foregroundServices; // Running any services that are foreground? |
| 61 | boolean bad; // True if disabled in the bad process list |
| 62 | IBinder forcingToForeground;// Token that is forcing this process to be foreground |
| 63 | int adjSeq; // Sequence id for identifying repeated trav |
| 64 | ComponentName instrumentationClass;// class installed to instrument app |
| 65 | String instrumentationProfileFile; // where to save profiling |
| 66 | IInstrumentationWatcher instrumentationWatcher; // who is waiting |
| 67 | Bundle instrumentationArguments;// as given to us |
| 68 | ComponentName instrumentationResultClass;// copy of instrumentationClass |
| 69 | BroadcastRecord curReceiver;// receiver currently running in the app |
| 70 | long lastRequestedGc; // When we last asked the app to do a gc |
| 71 | int lastPss; // Last pss size reported by app. |
| 72 | |
| 73 | // contains HistoryRecord objects |
| 74 | final ArrayList activities = new ArrayList(); |
| 75 | // all ServiceRecord running in this process |
| 76 | final HashSet services = new HashSet(); |
| 77 | // services that are currently executing code (need to remain foreground). |
| 78 | final HashSet<ServiceRecord> executingServices |
| 79 | = new HashSet<ServiceRecord>(); |
| 80 | // All ConnectionRecord this process holds |
| 81 | final HashSet<ConnectionRecord> connections |
| 82 | = new HashSet<ConnectionRecord>(); |
| 83 | // all IIntentReceivers that are registered from this process. |
| 84 | final HashSet<ReceiverList> receivers = new HashSet<ReceiverList>(); |
| 85 | // class (String) -> ContentProviderRecord |
| 86 | final HashMap pubProviders = new HashMap(); |
| 87 | // All ContentProviderRecord process is using |
| 88 | final HashSet conProviders = new HashSet(); |
| 89 | |
| 90 | boolean persistent; // always keep this application running? |
| 91 | boolean crashing; // are we in the process of crashing? |
| 92 | Dialog crashDialog; // dialog being displayed due to crash. |
| 93 | boolean notResponding; // does the app have a not responding dialog? |
| 94 | Dialog anrDialog; // dialog being displayed due to app not resp. |
| 95 | boolean removed; // has app package been removed from device? |
| 96 | boolean debugging; // was app launched for debugging? |
| 97 | int persistentActivities; // number of activities that are persistent |
| 98 | boolean waitedForDebugger; // has process show wait for debugger dialog? |
| 99 | Dialog waitDialog; // current wait for debugger dialog |
| 100 | |
| 101 | // These reports are generated & stored when an app gets into an error condition. |
| 102 | // They will be "null" when all is OK. |
| 103 | ActivityManager.ProcessErrorStateInfo crashingReport; |
| 104 | ActivityManager.ProcessErrorStateInfo notRespondingReport; |
| 105 | |
| 106 | void dump(PrintWriter pw, String prefix) { |
| 107 | pw.println(prefix + this); |
| 108 | pw.println(prefix + "class=" + info.className); |
| 109 | pw.println(prefix+"manageSpaceActivityName="+info.manageSpaceActivityName); |
| 110 | pw.println(prefix + "dir=" + info.sourceDir + " publicDir=" + info.publicSourceDir |
| 111 | + " data=" + info.dataDir); |
| 112 | pw.println(prefix + "packageList=" + pkgList); |
| 113 | pw.println(prefix + "instrumentationClass=" + instrumentationClass |
| 114 | + " instrumentationProfileFile=" + instrumentationProfileFile); |
| 115 | pw.println(prefix + "instrumentationArguments=" + instrumentationArguments); |
| 116 | pw.println(prefix + "thread=" + thread + " curReceiver=" + curReceiver); |
| 117 | pw.println(prefix + "pid=" + pid + " starting=" + starting |
| 118 | + " lastPss=" + lastPss); |
| 119 | pw.println(prefix + "maxAdj=" + maxAdj + " hiddenAdj=" + hiddenAdj |
| 120 | + " curRawAdj=" + curRawAdj + " setRawAdj=" + setRawAdj |
| 121 | + " curAdj=" + curAdj + " setAdj=" + setAdj); |
| 122 | pw.println(prefix + "isForeground=" + isForeground |
| 123 | + " setIsForeground=" + setIsForeground |
| 124 | + " foregroundServices=" + foregroundServices |
| 125 | + " forcingToForeground=" + forcingToForeground); |
| 126 | pw.println(prefix + "persistent=" + persistent + " removed=" + removed |
| 127 | + " persistentActivities=" + persistentActivities); |
| 128 | pw.println(prefix + "debugging=" + debugging |
| 129 | + " crashing=" + crashing + " " + crashDialog |
| 130 | + " notResponding=" + notResponding + " " + anrDialog |
| 131 | + " bad=" + bad); |
| 132 | pw.println(prefix + "activities=" + activities); |
| 133 | pw.println(prefix + "services=" + services); |
| 134 | pw.println(prefix + "executingServices=" + executingServices); |
| 135 | pw.println(prefix + "connections=" + connections); |
| 136 | pw.println(prefix + "pubProviders=" + pubProviders); |
| 137 | pw.println(prefix + "conProviders=" + conProviders); |
| 138 | pw.println(prefix + "receivers=" + receivers); |
| 139 | } |
| 140 | |
| 141 | ProcessRecord(BatteryStatsImpl.Uid.Proc _batteryStats, IApplicationThread _thread, |
| 142 | ApplicationInfo _info, String _processName) { |
| 143 | batteryStats = _batteryStats; |
| 144 | info = _info; |
| 145 | processName = _processName; |
| 146 | pkgList.add(_info.packageName); |
| 147 | thread = _thread; |
| 148 | maxAdj = ActivityManagerService.EMPTY_APP_ADJ; |
| 149 | hiddenAdj = ActivityManagerService.HIDDEN_APP_MIN_ADJ; |
| 150 | curRawAdj = setRawAdj = -100; |
| 151 | curAdj = setAdj = -100; |
| 152 | persistent = false; |
| 153 | removed = false; |
| 154 | persistentActivities = 0; |
| 155 | } |
| 156 | |
| 157 | /** |
| 158 | * This method returns true if any of the activities within the process record are interesting |
| 159 | * to the user. See HistoryRecord.isInterestingToUserLocked() |
| 160 | */ |
| 161 | public boolean isInterestingToUserLocked() { |
| 162 | final int size = activities.size(); |
| 163 | for (int i = 0 ; i < size ; i++) { |
| 164 | HistoryRecord r = (HistoryRecord) activities.get(i); |
| 165 | if (r.isInterestingToUserLocked()) { |
| 166 | return true; |
| 167 | } |
| 168 | } |
| 169 | return false; |
| 170 | } |
| 171 | |
| 172 | public void stopFreezingAllLocked() { |
| 173 | int i = activities.size(); |
| 174 | while (i > 0) { |
| 175 | i--; |
| 176 | ((HistoryRecord)activities.get(i)).stopFreezingScreenLocked(true); |
| 177 | } |
| 178 | } |
| 179 | |
| 180 | public void requestPss() { |
| 181 | IApplicationThread localThread = thread; |
| 182 | if (localThread != null) { |
| 183 | try { |
| 184 | localThread.requestPss(); |
| 185 | } catch (RemoteException e) { |
| 186 | } |
| 187 | } |
| 188 | } |
| 189 | |
| 190 | public String toString() { |
| 191 | return "ProcessRecord{" |
| 192 | + Integer.toHexString(System.identityHashCode(this)) |
| 193 | + " " + pid + ":" + processName + "/" + info.uid + "}"; |
| 194 | } |
| 195 | |
| 196 | /* |
| 197 | * Return true if package has been added false if not |
| 198 | */ |
| 199 | public boolean addPackage(String pkg) { |
| 200 | if (!pkgList.contains(pkg)) { |
| 201 | pkgList.add(pkg); |
| 202 | return true; |
| 203 | } |
| 204 | return false; |
| 205 | } |
| 206 | |
| 207 | /* |
| 208 | * Delete all packages from list except the package indicated in info |
| 209 | */ |
| 210 | public void resetPackageList() { |
| 211 | pkgList.clear(); |
| 212 | pkgList.add(info.packageName); |
| 213 | } |
| 214 | |
| 215 | public String[] getPackageList() { |
| 216 | int size = pkgList.size(); |
| 217 | if (size == 0) { |
| 218 | return null; |
| 219 | } |
| 220 | String list[] = new String[size]; |
| 221 | pkgList.toArray(list); |
| 222 | return list; |
| 223 | } |
| 224 | } |