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