ServiceRecord.java revision f210d6b75e2c0fe60b90c074ff9f615c1137f23e
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.println(prefix + this); 84 pw.println(prefix + "intent=" + intent.getIntent()); 85 pw.println(prefix + "packageName=" + packageName); 86 pw.println(prefix + "processName=" + processName); 87 pw.println(prefix + "permission=" + permission); 88 pw.println(prefix + "baseDir=" + baseDir+ " resDir=" + resDir + " dataDir=" + dataDir); 89 pw.println(prefix + "app=" + app); 90 pw.println(prefix + "isForeground=" + isForeground 91 + " lastActivity=" + lastActivity); 92 pw.println(prefix + "startRequested=" + startRequested 93 + " startId=" + lastStartId 94 + " executeNesting=" + executeNesting 95 + " executingStart=" + executingStart 96 + " crashCount=" + crashCount); 97 pw.println(prefix + "totalRestartCount=" + totalRestartCount 98 + " restartCount=" + restartCount 99 + " restartDelay=" + restartDelay 100 + " restartTime=" + restartTime 101 + " nextRestartTime=" + nextRestartTime); 102 if (bindings.size() > 0) { 103 pw.println(prefix + "Bindings:"); 104 Iterator<IntentBindRecord> it = bindings.values().iterator(); 105 while (it.hasNext()) { 106 IntentBindRecord b = it.next(); 107 pw.println(prefix + "Binding " + b); 108 b.dump(pw, prefix + " "); 109 } 110 } 111 if (connections.size() > 0) { 112 pw.println(prefix + "All Connections:"); 113 Iterator<ConnectionRecord> it = connections.values().iterator(); 114 while (it.hasNext()) { 115 ConnectionRecord c = it.next(); 116 pw.println(prefix + " " + c); 117 } 118 } 119 } 120 121 ServiceRecord(BatteryStatsImpl.Uid.Pkg.Serv servStats, ComponentName name, 122 Intent.FilterComparison intent, ServiceInfo sInfo, Runnable restarter) { 123 this.stats = servStats; 124 this.name = name; 125 shortName = name.flattenToShortString(); 126 this.intent = intent; 127 serviceInfo = sInfo; 128 appInfo = sInfo.applicationInfo; 129 packageName = sInfo.applicationInfo.packageName; 130 processName = sInfo.processName; 131 permission = sInfo.permission; 132 baseDir = sInfo.applicationInfo.sourceDir; 133 resDir = sInfo.applicationInfo.publicSourceDir; 134 dataDir = sInfo.applicationInfo.dataDir; 135 exported = sInfo.exported; 136 this.restarter = restarter; 137 createTime = lastActivity = SystemClock.uptimeMillis(); 138 } 139 140 public AppBindRecord retrieveAppBindingLocked(Intent intent, 141 ProcessRecord app) { 142 Intent.FilterComparison filter = new Intent.FilterComparison(intent); 143 IntentBindRecord i = bindings.get(filter); 144 if (i == null) { 145 i = new IntentBindRecord(this, filter); 146 bindings.put(filter, i); 147 } 148 AppBindRecord a = i.apps.get(app); 149 if (a != null) { 150 return a; 151 } 152 a = new AppBindRecord(this, i, app); 153 i.apps.put(app, a); 154 return a; 155 } 156 157 public void resetRestartCounter() { 158 restartCount = 0; 159 restartDelay = 0; 160 restartTime = 0; 161 } 162 163 public String toString() { 164 if (stringName != null) { 165 return stringName; 166 } 167 StringBuilder sb = new StringBuilder(128); 168 sb.append("ServiceRecord{"); 169 sb.append(Integer.toHexString(System.identityHashCode(this))); 170 sb.append(' '); 171 sb.append(shortName); 172 sb.append('}'); 173 return stringName = sb.toString(); 174 } 175} 176