/services/java/com/android/server/am/ServiceRecord.java

https://github.com/aizuzi/platform_frameworks_base · Java · 543 lines · 465 code · 35 blank · 43 comment · 100 complexity · 9cd6742b21e8955f857fef317a2bbfb9 MD5 · raw file

  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. package com.android.server.am;
  17. import com.android.internal.app.ProcessStats;
  18. import com.android.internal.os.BatteryStatsImpl;
  19. import com.android.server.NotificationManagerService;
  20. import android.app.INotificationManager;
  21. import android.app.Notification;
  22. import android.app.NotificationManager;
  23. import android.app.PendingIntent;
  24. import android.content.ComponentName;
  25. import android.content.Context;
  26. import android.content.Intent;
  27. import android.content.pm.ApplicationInfo;
  28. import android.content.pm.PackageManager;
  29. import android.content.pm.ServiceInfo;
  30. import android.net.Uri;
  31. import android.os.Binder;
  32. import android.os.IBinder;
  33. import android.os.RemoteException;
  34. import android.os.SystemClock;
  35. import android.os.UserHandle;
  36. import android.provider.Settings;
  37. import android.util.ArrayMap;
  38. import android.util.Slog;
  39. import android.util.TimeUtils;
  40. import java.io.PrintWriter;
  41. import java.util.ArrayList;
  42. import java.util.List;
  43. /**
  44. * A running application service.
  45. */
  46. final class ServiceRecord extends Binder {
  47. // Maximum number of delivery attempts before giving up.
  48. static final int MAX_DELIVERY_COUNT = 3;
  49. // Maximum number of times it can fail during execution before giving up.
  50. static final int MAX_DONE_EXECUTING_COUNT = 6;
  51. final ActivityManagerService ams;
  52. final BatteryStatsImpl.Uid.Pkg.Serv stats;
  53. final ComponentName name; // service component.
  54. final String shortName; // name.flattenToShortString().
  55. final Intent.FilterComparison intent;
  56. // original intent used to find service.
  57. final ServiceInfo serviceInfo;
  58. // all information about the service.
  59. final ApplicationInfo appInfo;
  60. // information about service's app.
  61. final int userId; // user that this service is running as
  62. final String packageName; // the package implementing intent's component
  63. final String processName; // process where this component wants to run
  64. final String permission;// permission needed to access service
  65. final String baseDir; // where activity source (resources etc) located
  66. final String resDir; // where public activity source (public resources etc) located
  67. final String dataDir; // where activity data should go
  68. final boolean exported; // from ServiceInfo.exported
  69. final Runnable restarter; // used to schedule retries of starting the service
  70. final long createTime; // when this service was created
  71. final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings
  72. = new ArrayMap<Intent.FilterComparison, IntentBindRecord>();
  73. // All active bindings to the service.
  74. final ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections
  75. = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>();
  76. // IBinder -> ConnectionRecord of all bound clients
  77. ProcessRecord app; // where this service is running or null.
  78. ProcessRecord isolatedProc; // keep track of isolated process, if requested
  79. ProcessStats.ServiceState tracker; // tracking service execution, may be null
  80. ProcessStats.ServiceState restartTracker; // tracking service restart
  81. boolean delayed; // are we waiting to start this service in the background?
  82. boolean isForeground; // is service currently in foreground mode?
  83. int foregroundId; // Notification ID of last foreground req.
  84. Notification foregroundNoti; // Notification record of foreground state.
  85. long lastActivity; // last time there was some activity on the service.
  86. long startingBgTimeout; // time at which we scheduled this for a delayed start.
  87. boolean startRequested; // someone explicitly called start?
  88. boolean delayedStop; // service has been stopped but is in a delayed start?
  89. boolean stopIfKilled; // last onStart() said to stop if service killed?
  90. boolean callStart; // last onStart() has asked to alway be called on restart.
  91. int executeNesting; // number of outstanding operations keeping foreground.
  92. boolean executeFg; // should we be executing in the foreground?
  93. long executingStart; // start time of last execute request.
  94. boolean createdFromFg; // was this service last created due to a foreground process call?
  95. int crashCount; // number of times proc has crashed with service running
  96. int totalRestartCount; // number of times we have had to restart.
  97. int restartCount; // number of restarts performed in a row.
  98. long restartDelay; // delay until next restart attempt.
  99. long restartTime; // time of last restart.
  100. long nextRestartTime; // time when restartDelay will expire.
  101. String stringName; // caching of toString
  102. private int lastStartId; // identifier of most recent start request.
  103. static class StartItem {
  104. final ServiceRecord sr;
  105. final boolean taskRemoved;
  106. final int id;
  107. final Intent intent;
  108. final ActivityManagerService.NeededUriGrants neededGrants;
  109. long deliveredTime;
  110. int deliveryCount;
  111. int doneExecutingCount;
  112. UriPermissionOwner uriPermissions;
  113. String stringName; // caching of toString
  114. StartItem(ServiceRecord _sr, boolean _taskRemoved, int _id, Intent _intent,
  115. ActivityManagerService.NeededUriGrants _neededGrants) {
  116. sr = _sr;
  117. taskRemoved = _taskRemoved;
  118. id = _id;
  119. intent = _intent;
  120. neededGrants = _neededGrants;
  121. }
  122. UriPermissionOwner getUriPermissionsLocked() {
  123. if (uriPermissions == null) {
  124. uriPermissions = new UriPermissionOwner(sr.ams, this);
  125. }
  126. return uriPermissions;
  127. }
  128. void removeUriPermissionsLocked() {
  129. if (uriPermissions != null) {
  130. uriPermissions.removeUriPermissionsLocked();
  131. uriPermissions = null;
  132. }
  133. }
  134. public String toString() {
  135. if (stringName != null) {
  136. return stringName;
  137. }
  138. StringBuilder sb = new StringBuilder(128);
  139. sb.append("ServiceRecord{")
  140. .append(Integer.toHexString(System.identityHashCode(sr)))
  141. .append(' ').append(sr.shortName)
  142. .append(" StartItem ")
  143. .append(Integer.toHexString(System.identityHashCode(this)))
  144. .append(" id=").append(id).append('}');
  145. return stringName = sb.toString();
  146. }
  147. }
  148. final ArrayList<StartItem> deliveredStarts = new ArrayList<StartItem>();
  149. // start() arguments which been delivered.
  150. final ArrayList<StartItem> pendingStarts = new ArrayList<StartItem>();
  151. // start() arguments that haven't yet been delivered.
  152. void dumpStartList(PrintWriter pw, String prefix, List<StartItem> list, long now) {
  153. final int N = list.size();
  154. for (int i=0; i<N; i++) {
  155. StartItem si = list.get(i);
  156. pw.print(prefix); pw.print("#"); pw.print(i);
  157. pw.print(" id="); pw.print(si.id);
  158. if (now != 0) {
  159. pw.print(" dur=");
  160. TimeUtils.formatDuration(si.deliveredTime, now, pw);
  161. }
  162. if (si.deliveryCount != 0) {
  163. pw.print(" dc="); pw.print(si.deliveryCount);
  164. }
  165. if (si.doneExecutingCount != 0) {
  166. pw.print(" dxc="); pw.print(si.doneExecutingCount);
  167. }
  168. pw.println("");
  169. pw.print(prefix); pw.print(" intent=");
  170. if (si.intent != null) pw.println(si.intent.toString());
  171. else pw.println("null");
  172. if (si.neededGrants != null) {
  173. pw.print(prefix); pw.print(" neededGrants=");
  174. pw.println(si.neededGrants);
  175. }
  176. if (si.uriPermissions != null) {
  177. if (si.uriPermissions.readUriPermissions != null) {
  178. pw.print(prefix); pw.print(" readUriPermissions=");
  179. pw.println(si.uriPermissions.readUriPermissions);
  180. }
  181. if (si.uriPermissions.writeUriPermissions != null) {
  182. pw.print(prefix); pw.print(" writeUriPermissions=");
  183. pw.println(si.uriPermissions.writeUriPermissions);
  184. }
  185. }
  186. }
  187. }
  188. void dump(PrintWriter pw, String prefix) {
  189. pw.print(prefix); pw.print("intent={");
  190. pw.print(intent.getIntent().toShortString(false, true, false, true));
  191. pw.println('}');
  192. pw.print(prefix); pw.print("packageName="); pw.println(packageName);
  193. pw.print(prefix); pw.print("processName="); pw.println(processName);
  194. if (permission != null) {
  195. pw.print(prefix); pw.print("permission="); pw.println(permission);
  196. }
  197. long now = SystemClock.uptimeMillis();
  198. long nowReal = SystemClock.elapsedRealtime();
  199. pw.print(prefix); pw.print("baseDir="); pw.println(baseDir);
  200. if (!resDir.equals(baseDir)) {
  201. pw.print(prefix); pw.print("resDir="); pw.println(resDir);
  202. }
  203. pw.print(prefix); pw.print("dataDir="); pw.println(dataDir);
  204. pw.print(prefix); pw.print("app="); pw.println(app);
  205. if (isolatedProc != null) {
  206. pw.print(prefix); pw.print("isolatedProc="); pw.println(isolatedProc);
  207. }
  208. if (delayed) {
  209. pw.print(prefix); pw.print("delayed="); pw.println(delayed);
  210. }
  211. if (isForeground || foregroundId != 0) {
  212. pw.print(prefix); pw.print("isForeground="); pw.print(isForeground);
  213. pw.print(" foregroundId="); pw.print(foregroundId);
  214. pw.print(" foregroundNoti="); pw.println(foregroundNoti);
  215. }
  216. pw.print(prefix); pw.print("createTime=");
  217. TimeUtils.formatDuration(createTime, nowReal, pw);
  218. pw.print(" startingBgTimeout=");
  219. TimeUtils.formatDuration(startingBgTimeout, now, pw);
  220. pw.println();
  221. pw.print(prefix); pw.print("lastActivity=");
  222. TimeUtils.formatDuration(lastActivity, now, pw);
  223. pw.print(" restartTime=");
  224. TimeUtils.formatDuration(restartTime, now, pw);
  225. pw.print(" createdFromFg="); pw.println(createdFromFg);
  226. if (startRequested || delayedStop || lastStartId != 0) {
  227. pw.print(prefix); pw.print("startRequested="); pw.print(startRequested);
  228. pw.print(" delayedStop="); pw.print(delayedStop);
  229. pw.print(" stopIfKilled="); pw.print(stopIfKilled);
  230. pw.print(" callStart="); pw.print(callStart);
  231. pw.print(" lastStartId="); pw.println(lastStartId);
  232. }
  233. if (executeNesting != 0) {
  234. pw.print(prefix); pw.print("executeNesting="); pw.print(executeNesting);
  235. pw.print(" executeFg="); pw.print(executeFg);
  236. pw.print(" executingStart=");
  237. TimeUtils.formatDuration(executingStart, now, pw);
  238. pw.println();
  239. }
  240. if (crashCount != 0 || restartCount != 0
  241. || restartDelay != 0 || nextRestartTime != 0) {
  242. pw.print(prefix); pw.print("restartCount="); pw.print(restartCount);
  243. pw.print(" restartDelay=");
  244. TimeUtils.formatDuration(restartDelay, now, pw);
  245. pw.print(" nextRestartTime=");
  246. TimeUtils.formatDuration(nextRestartTime, now, pw);
  247. pw.print(" crashCount="); pw.println(crashCount);
  248. }
  249. if (deliveredStarts.size() > 0) {
  250. pw.print(prefix); pw.println("Delivered Starts:");
  251. dumpStartList(pw, prefix, deliveredStarts, now);
  252. }
  253. if (pendingStarts.size() > 0) {
  254. pw.print(prefix); pw.println("Pending Starts:");
  255. dumpStartList(pw, prefix, pendingStarts, 0);
  256. }
  257. if (bindings.size() > 0) {
  258. pw.print(prefix); pw.println("Bindings:");
  259. for (int i=0; i<bindings.size(); i++) {
  260. IntentBindRecord b = bindings.valueAt(i);
  261. pw.print(prefix); pw.print("* IntentBindRecord{");
  262. pw.print(Integer.toHexString(System.identityHashCode(b)));
  263. if ((b.collectFlags()&Context.BIND_AUTO_CREATE) != 0) {
  264. pw.append(" CREATE");
  265. }
  266. pw.println("}:");
  267. b.dumpInService(pw, prefix + " ");
  268. }
  269. }
  270. if (connections.size() > 0) {
  271. pw.print(prefix); pw.println("All Connections:");
  272. for (int conni=0; conni<connections.size(); conni++) {
  273. ArrayList<ConnectionRecord> c = connections.valueAt(conni);
  274. for (int i=0; i<c.size(); i++) {
  275. pw.print(prefix); pw.print(" "); pw.println(c.get(i));
  276. }
  277. }
  278. }
  279. }
  280. ServiceRecord(ActivityManagerService ams,
  281. BatteryStatsImpl.Uid.Pkg.Serv servStats, ComponentName name,
  282. Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg,
  283. Runnable restarter) {
  284. this.ams = ams;
  285. this.stats = servStats;
  286. this.name = name;
  287. shortName = name.flattenToShortString();
  288. this.intent = intent;
  289. serviceInfo = sInfo;
  290. appInfo = sInfo.applicationInfo;
  291. packageName = sInfo.applicationInfo.packageName;
  292. processName = sInfo.processName;
  293. permission = sInfo.permission;
  294. baseDir = sInfo.applicationInfo.sourceDir;
  295. resDir = sInfo.applicationInfo.publicSourceDir;
  296. dataDir = sInfo.applicationInfo.dataDir;
  297. exported = sInfo.exported;
  298. this.restarter = restarter;
  299. createTime = SystemClock.elapsedRealtime();
  300. lastActivity = SystemClock.uptimeMillis();
  301. userId = UserHandle.getUserId(appInfo.uid);
  302. createdFromFg = callerIsFg;
  303. }
  304. public ProcessStats.ServiceState getTracker() {
  305. if (tracker != null) {
  306. return tracker;
  307. }
  308. if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
  309. tracker = ams.mProcessStats.getServiceStateLocked(serviceInfo.packageName,
  310. serviceInfo.applicationInfo.uid, serviceInfo.processName, serviceInfo.name);
  311. tracker.applyNewOwner(this);
  312. }
  313. return tracker;
  314. }
  315. public void forceClearTracker() {
  316. if (tracker != null) {
  317. tracker.clearCurrentOwner(this, true);
  318. tracker = null;
  319. }
  320. }
  321. public void makeRestarting(int memFactor, long now) {
  322. if (restartTracker == null) {
  323. if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
  324. restartTracker = ams.mProcessStats.getServiceStateLocked(serviceInfo.packageName,
  325. serviceInfo.applicationInfo.uid, serviceInfo.processName, serviceInfo.name);
  326. }
  327. if (restartTracker == null) {
  328. return;
  329. }
  330. }
  331. restartTracker.setRestarting(true, memFactor, now);
  332. }
  333. public AppBindRecord retrieveAppBindingLocked(Intent intent,
  334. ProcessRecord app) {
  335. Intent.FilterComparison filter = new Intent.FilterComparison(intent);
  336. IntentBindRecord i = bindings.get(filter);
  337. if (i == null) {
  338. i = new IntentBindRecord(this, filter);
  339. bindings.put(filter, i);
  340. }
  341. AppBindRecord a = i.apps.get(app);
  342. if (a != null) {
  343. return a;
  344. }
  345. a = new AppBindRecord(this, i, app);
  346. i.apps.put(app, a);
  347. return a;
  348. }
  349. public boolean hasAutoCreateConnections() {
  350. // XXX should probably keep a count of the number of auto-create
  351. // connections directly in the service.
  352. for (int conni=connections.size()-1; conni>=0; conni--) {
  353. ArrayList<ConnectionRecord> cr = connections.valueAt(conni);
  354. for (int i=0; i<cr.size(); i++) {
  355. if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
  356. return true;
  357. }
  358. }
  359. }
  360. return false;
  361. }
  362. public void resetRestartCounter() {
  363. restartCount = 0;
  364. restartDelay = 0;
  365. restartTime = 0;
  366. }
  367. public StartItem findDeliveredStart(int id, boolean remove) {
  368. final int N = deliveredStarts.size();
  369. for (int i=0; i<N; i++) {
  370. StartItem si = deliveredStarts.get(i);
  371. if (si.id == id) {
  372. if (remove) deliveredStarts.remove(i);
  373. return si;
  374. }
  375. }
  376. return null;
  377. }
  378. public int getLastStartId() {
  379. return lastStartId;
  380. }
  381. public int makeNextStartId() {
  382. lastStartId++;
  383. if (lastStartId < 1) {
  384. lastStartId = 1;
  385. }
  386. return lastStartId;
  387. }
  388. public void postNotification() {
  389. final int appUid = appInfo.uid;
  390. final int appPid = app.pid;
  391. if (foregroundId != 0 && foregroundNoti != null) {
  392. // Do asynchronous communication with notification manager to
  393. // avoid deadlocks.
  394. final String localPackageName = packageName;
  395. final int localForegroundId = foregroundId;
  396. final Notification localForegroundNoti = foregroundNoti;
  397. ams.mHandler.post(new Runnable() {
  398. public void run() {
  399. NotificationManagerService nm =
  400. (NotificationManagerService) NotificationManager.getService();
  401. if (nm == null) {
  402. return;
  403. }
  404. try {
  405. if (localForegroundNoti.icon == 0) {
  406. // It is not correct for the caller to supply a notification
  407. // icon, but this used to be able to slip through, so for
  408. // those dirty apps give it the app's icon.
  409. localForegroundNoti.icon = appInfo.icon;
  410. // Do not allow apps to present a sneaky invisible content view either.
  411. localForegroundNoti.contentView = null;
  412. localForegroundNoti.bigContentView = null;
  413. CharSequence appName = appInfo.loadLabel(
  414. ams.mContext.getPackageManager());
  415. if (appName == null) {
  416. appName = appInfo.packageName;
  417. }
  418. Context ctx = null;
  419. try {
  420. ctx = ams.mContext.createPackageContext(
  421. appInfo.packageName, 0);
  422. Intent runningIntent = new Intent(
  423. Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
  424. runningIntent.setData(Uri.fromParts("package",
  425. appInfo.packageName, null));
  426. PendingIntent pi = PendingIntent.getActivity(ams.mContext, 0,
  427. runningIntent, PendingIntent.FLAG_UPDATE_CURRENT);
  428. localForegroundNoti.setLatestEventInfo(ctx,
  429. ams.mContext.getString(
  430. com.android.internal.R.string
  431. .app_running_notification_title,
  432. appName),
  433. ams.mContext.getString(
  434. com.android.internal.R.string
  435. .app_running_notification_text,
  436. appName),
  437. pi);
  438. } catch (PackageManager.NameNotFoundException e) {
  439. localForegroundNoti.icon = 0;
  440. }
  441. }
  442. if (localForegroundNoti.icon == 0) {
  443. // Notifications whose icon is 0 are defined to not show
  444. // a notification, silently ignoring it. We don't want to
  445. // just ignore it, we want to prevent the service from
  446. // being foreground.
  447. throw new RuntimeException("icon must be non-zero");
  448. }
  449. int[] outId = new int[1];
  450. nm.enqueueNotificationInternal(localPackageName, localPackageName,
  451. appUid, appPid, null, localForegroundId, localForegroundNoti,
  452. outId, userId);
  453. } catch (RuntimeException e) {
  454. Slog.w(ActivityManagerService.TAG,
  455. "Error showing notification for service", e);
  456. // If it gave us a garbage notification, it doesn't
  457. // get to be foreground.
  458. ams.setServiceForeground(name, ServiceRecord.this,
  459. 0, null, true);
  460. ams.crashApplication(appUid, appPid, localPackageName,
  461. "Bad notification for startForeground: " + e);
  462. }
  463. }
  464. });
  465. }
  466. }
  467. public void cancelNotification() {
  468. if (foregroundId != 0) {
  469. // Do asynchronous communication with notification manager to
  470. // avoid deadlocks.
  471. final String localPackageName = packageName;
  472. final int localForegroundId = foregroundId;
  473. ams.mHandler.post(new Runnable() {
  474. public void run() {
  475. INotificationManager inm = NotificationManager.getService();
  476. if (inm == null) {
  477. return;
  478. }
  479. try {
  480. inm.cancelNotificationWithTag(localPackageName, null,
  481. localForegroundId, userId);
  482. } catch (RuntimeException e) {
  483. Slog.w(ActivityManagerService.TAG,
  484. "Error canceling notification for service", e);
  485. } catch (RemoteException e) {
  486. }
  487. }
  488. });
  489. }
  490. }
  491. public void clearDeliveredStartsLocked() {
  492. for (int i=deliveredStarts.size()-1; i>=0; i--) {
  493. deliveredStarts.get(i).removeUriPermissionsLocked();
  494. }
  495. deliveredStarts.clear();
  496. }
  497. public String toString() {
  498. if (stringName != null) {
  499. return stringName;
  500. }
  501. StringBuilder sb = new StringBuilder(128);
  502. sb.append("ServiceRecord{")
  503. .append(Integer.toHexString(System.identityHashCode(this)))
  504. .append(" u").append(userId)
  505. .append(' ').append(shortName).append('}');
  506. return stringName = sb.toString();
  507. }
  508. }