ServiceRecord.java revision 1d442e0d990b581357f33f5463c7c5cb49b551e8
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 17package com.android.server.am; 18 19import com.android.internal.os.BatteryStatsImpl; 20 21import android.content.ComponentName; 22import android.content.Intent; 23import android.content.pm.ApplicationInfo; 24import android.content.pm.ServiceInfo; 25import android.os.Binder; 26import android.os.IBinder; 27import android.os.SystemClock; 28 29import java.io.PrintWriter; 30import java.util.ArrayList; 31import java.util.HashMap; 32import java.util.Iterator; 33import java.util.List; 34 35/** 36 * A running application service. 37 */ 38class ServiceRecord extends Binder { 39 final BatteryStatsImpl.Uid.Pkg.Serv stats; 40 final ComponentName name; // service component. 41 final String shortName; // name.flattenToShortString(). 42 final Intent.FilterComparison intent; 43 // original intent used to find service. 44 final ServiceInfo serviceInfo; 45 // all information about the service. 46 final ApplicationInfo appInfo; 47 // information about service's app. 48 final String packageName; // the package implementing intent's component 49 final String processName; // process where this component wants to run 50 final String permission;// permission needed to access service 51 final String baseDir; // where activity source (resources etc) located 52 final String resDir; // where public activity source (public resources etc) located 53 final String dataDir; // where activity data should go 54 final boolean exported; // from ServiceInfo.exported 55 final Runnable restarter; // used to schedule retries of starting the service 56 final long createTime; // when this service was created 57 final HashMap<Intent.FilterComparison, IntentBindRecord> bindings 58 = new HashMap<Intent.FilterComparison, IntentBindRecord>(); 59 // All active bindings to the service. 60 final HashMap<IBinder, ConnectionRecord> connections 61 = new HashMap<IBinder, ConnectionRecord>(); 62 // IBinder -> ConnectionRecord of all bound clients 63 final List<Intent> startArgs = new ArrayList<Intent>(); 64 // start() arguments that haven't yet been delivered. 65 66 ProcessRecord app; // where this service is running or null. 67 boolean isForeground; // asked to run as a foreground service? 68 long lastActivity; // last time there was some activity on the service. 69 boolean startRequested; // someone explicitly called start? 70 int lastStartId; // identifier of most recent start request. 71 int executeNesting; // number of outstanding operations keeping foreground. 72 long executingStart; // start time of last execute request. 73 int crashCount; // number of times proc has crashed with service running 74 int totalRestartCount; // number of times we have had to restart. 75 int restartCount; // number of restarts performed in a row. 76 long restartDelay; // delay until next restart attempt. 77 long restartTime; // time of last restart. 78 long nextRestartTime; // time when restartDelay will expire. 79 80 String stringName; // caching of toString 81 82 void dump(PrintWriter pw, String prefix) { 83 pw.print(prefix); pw.print("intent={"); 84 pw.print(intent.getIntent().toShortString(true, false)); 85 pw.println('}'); 86 pw.print(prefix); pw.print("packageName="); pw.println(packageName); 87 pw.print(prefix); pw.print("processName="); pw.println(processName); 88 if (permission != null) { 89 pw.print(prefix); pw.print("permission="); pw.println(permission); 90 } 91 pw.print(prefix); pw.print("baseDir="); pw.print(baseDir); 92 if (!resDir.equals(baseDir)) pw.print(" resDir="); pw.print(resDir); 93 pw.print(" dataDir="); pw.println(dataDir); 94 pw.print(prefix); pw.print("app="); pw.println(app); 95 pw.print(prefix); pw.print("isForeground="); pw.print(isForeground); 96 pw.print(" lastActivity="); pw.println(lastActivity); 97 pw.print(prefix); pw.print("startRequested="); pw.print(startRequested); 98 pw.print(" startId="); pw.print(lastStartId); 99 pw.print(" executeNesting="); pw.print(executeNesting); 100 pw.print(" executingStart="); pw.print(executingStart); 101 pw.print(" crashCount="); pw.println(crashCount); 102 pw.print(prefix); pw.print("totalRestartCount="); pw.print(totalRestartCount); 103 pw.print(" restartCount="); pw.print(restartCount); 104 pw.print(" restartDelay="); pw.print(restartDelay); 105 pw.print(" restartTime="); pw.print(restartTime); 106 pw.print(" nextRestartTime="); pw.println(nextRestartTime); 107 if (bindings.size() > 0) { 108 Iterator<IntentBindRecord> it = bindings.values().iterator(); 109 while (it.hasNext()) { 110 IntentBindRecord b = it.next(); 111 pw.print(prefix); pw.print("* IntentBindRecord{"); 112 pw.print(Integer.toHexString(System.identityHashCode(b))); 113 pw.println("}:"); 114 b.dumpInService(pw, prefix + " "); 115 } 116 } 117 if (connections.size() > 0) { 118 pw.print(prefix); pw.println("All Connections:"); 119 Iterator<ConnectionRecord> it = connections.values().iterator(); 120 while (it.hasNext()) { 121 ConnectionRecord c = it.next(); 122 pw.print(prefix); pw.print(" "); pw.println(c); 123 } 124 } 125 } 126 127 ServiceRecord(BatteryStatsImpl.Uid.Pkg.Serv servStats, ComponentName name, 128 Intent.FilterComparison intent, ServiceInfo sInfo, Runnable restarter) { 129 this.stats = servStats; 130 this.name = name; 131 shortName = name.flattenToShortString(); 132 this.intent = intent; 133 serviceInfo = sInfo; 134 appInfo = sInfo.applicationInfo; 135 packageName = sInfo.applicationInfo.packageName; 136 processName = sInfo.processName; 137 permission = sInfo.permission; 138 baseDir = sInfo.applicationInfo.sourceDir; 139 resDir = sInfo.applicationInfo.publicSourceDir; 140 dataDir = sInfo.applicationInfo.dataDir; 141 exported = sInfo.exported; 142 this.restarter = restarter; 143 createTime = lastActivity = SystemClock.uptimeMillis(); 144 } 145 146 public AppBindRecord retrieveAppBindingLocked(Intent intent, 147 ProcessRecord app) { 148 Intent.FilterComparison filter = new Intent.FilterComparison(intent); 149 IntentBindRecord i = bindings.get(filter); 150 if (i == null) { 151 i = new IntentBindRecord(this, filter); 152 bindings.put(filter, i); 153 } 154 AppBindRecord a = i.apps.get(app); 155 if (a != null) { 156 return a; 157 } 158 a = new AppBindRecord(this, i, app); 159 i.apps.put(app, a); 160 return a; 161 } 162 163 public void resetRestartCounter() { 164 restartCount = 0; 165 restartDelay = 0; 166 restartTime = 0; 167 } 168 169 public String toString() { 170 if (stringName != null) { 171 return stringName; 172 } 173 StringBuilder sb = new StringBuilder(128); 174 sb.append("ServiceRecord{") 175 .append(Integer.toHexString(System.identityHashCode(this))) 176 .append(' ').append(shortName).append('}'); 177 return stringName = sb.toString(); 178 } 179} 180