• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.procstats.ServiceState;
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.Build;
37 import android.os.IBinder;
38 import android.os.RemoteException;
39 import android.os.SystemClock;
40 import android.os.UserHandle;
41 import android.provider.Settings;
42 import android.util.ArrayMap;
43 import android.util.Slog;
44 import android.util.TimeUtils;
45 import android.util.proto.ProtoOutputStream;
46 import android.util.proto.ProtoUtils;
47 
48 import java.io.PrintWriter;
49 import java.util.ArrayList;
50 import java.util.List;
51 import java.util.Objects;
52 
53 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
54 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
55 
56 /**
57  * A running application service.
58  */
59 final class ServiceRecord extends Binder implements ComponentName.WithComponentName {
60     private static final String TAG = TAG_WITH_CLASS_NAME ? "ServiceRecord" : TAG_AM;
61 
62     // Maximum number of delivery attempts before giving up.
63     static final int MAX_DELIVERY_COUNT = 3;
64 
65     // Maximum number of times it can fail during execution before giving up.
66     static final int MAX_DONE_EXECUTING_COUNT = 6;
67 
68     final ActivityManagerService ams;
69     final BatteryStatsImpl.Uid.Pkg.Serv stats;
70     final ComponentName name; // service component.
71     final String shortName; // name.flattenToShortString().
72     final Intent.FilterComparison intent;
73                             // original intent used to find service.
74     final ServiceInfo serviceInfo;
75                             // all information about the service.
76     ApplicationInfo appInfo;
77                             // information about service's app.
78     final int userId;       // user that this service is running as
79     final String packageName; // the package implementing intent's component
80     final String processName; // process where this component wants to run
81     final String permission;// permission needed to access service
82     final boolean exported; // from ServiceInfo.exported
83     final Runnable restarter; // used to schedule retries of starting the service
84     final long createRealTime;  // when this service was created
85     final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings
86             = new ArrayMap<Intent.FilterComparison, IntentBindRecord>();
87                             // All active bindings to the service.
88     final ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections
89             = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>();
90                             // IBinder -> ConnectionRecord of all bound clients
91 
92     ProcessRecord app;      // where this service is running or null.
93     ProcessRecord isolatedProc; // keep track of isolated process, if requested
94     ServiceState tracker; // tracking service execution, may be null
95     ServiceState restartTracker; // tracking service restart
96     boolean whitelistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT?
97     boolean delayed;        // are we waiting to start this service in the background?
98     boolean fgRequired;     // is the service required to go foreground after starting?
99     boolean fgWaiting;      // is a timeout for going foreground already scheduled?
100     boolean isForeground;   // is service currently in foreground mode?
101     int foregroundId;       // Notification ID of last foreground req.
102     Notification foregroundNoti; // Notification record of foreground state.
103     long lastActivity;      // last time there was some activity on the service.
104     long startingBgTimeout;  // time at which we scheduled this for a delayed start.
105     boolean startRequested; // someone explicitly called start?
106     boolean delayedStop;    // service has been stopped but is in a delayed start?
107     boolean stopIfKilled;   // last onStart() said to stop if service killed?
108     boolean callStart;      // last onStart() has asked to always be called on restart.
109     int executeNesting;     // number of outstanding operations keeping foreground.
110     boolean executeFg;      // should we be executing in the foreground?
111     long executingStart;    // start time of last execute request.
112     boolean createdFromFg;  // was this service last created due to a foreground process call?
113     int crashCount;         // number of times proc has crashed with service running
114     int totalRestartCount;  // number of times we have had to restart.
115     int restartCount;       // number of restarts performed in a row.
116     long restartDelay;      // delay until next restart attempt.
117     long restartTime;       // time of last restart.
118     long nextRestartTime;   // time when restartDelay will expire.
119     boolean destroying;     // set when we have started destroying the service
120     long destroyTime;       // time at which destory was initiated.
121 
122     String stringName;      // caching of toString
123 
124     private int lastStartId;    // identifier of most recent start request.
125 
126     static class StartItem {
127         final ServiceRecord sr;
128         final boolean taskRemoved;
129         final int id;
130         final int callingId;
131         final Intent intent;
132         final ActivityManagerService.NeededUriGrants neededGrants;
133         long deliveredTime;
134         int deliveryCount;
135         int doneExecutingCount;
136         UriPermissionOwner uriPermissions;
137 
138         String stringName;      // caching of toString
139 
StartItem(ServiceRecord _sr, boolean _taskRemoved, int _id, Intent _intent, ActivityManagerService.NeededUriGrants _neededGrants, int _callingId)140         StartItem(ServiceRecord _sr, boolean _taskRemoved, int _id, Intent _intent,
141                 ActivityManagerService.NeededUriGrants _neededGrants, int _callingId) {
142             sr = _sr;
143             taskRemoved = _taskRemoved;
144             id = _id;
145             intent = _intent;
146             neededGrants = _neededGrants;
147             callingId = _callingId;
148         }
149 
getUriPermissionsLocked()150         UriPermissionOwner getUriPermissionsLocked() {
151             if (uriPermissions == null) {
152                 uriPermissions = new UriPermissionOwner(sr.ams, this);
153             }
154             return uriPermissions;
155         }
156 
removeUriPermissionsLocked()157         void removeUriPermissionsLocked() {
158             if (uriPermissions != null) {
159                 uriPermissions.removeUriPermissionsLocked();
160                 uriPermissions = null;
161             }
162         }
163 
writeToProto(ProtoOutputStream proto, long fieldId, long now)164         public void writeToProto(ProtoOutputStream proto, long fieldId, long now) {
165             long token = proto.start(fieldId);
166             proto.write(ServiceRecordProto.StartItem.ID, id);
167             ProtoUtils.toDuration(proto,
168                     ServiceRecordProto.StartItem.DURATION, deliveredTime, now);
169             proto.write(ServiceRecordProto.StartItem.DELIVERY_COUNT, deliveryCount);
170             proto.write(ServiceRecordProto.StartItem.DONE_EXECUTING_COUNT, doneExecutingCount);
171             if (intent != null) {
172                 intent.writeToProto(proto, ServiceRecordProto.StartItem.INTENT, true, true,
173                         true, false);
174             }
175             if (neededGrants != null) {
176                 neededGrants.writeToProto(proto, ServiceRecordProto.StartItem.NEEDED_GRANTS);
177             }
178             if (uriPermissions != null) {
179                 uriPermissions.writeToProto(proto, ServiceRecordProto.StartItem.URI_PERMISSIONS);
180             }
181             proto.end(token);
182         }
183 
toString()184         public String toString() {
185             if (stringName != null) {
186                 return stringName;
187             }
188             StringBuilder sb = new StringBuilder(128);
189             sb.append("ServiceRecord{")
190                 .append(Integer.toHexString(System.identityHashCode(sr)))
191                 .append(' ').append(sr.shortName)
192                 .append(" StartItem ")
193                 .append(Integer.toHexString(System.identityHashCode(this)))
194                 .append(" id=").append(id).append('}');
195             return stringName = sb.toString();
196         }
197     }
198 
199     final ArrayList<StartItem> deliveredStarts = new ArrayList<StartItem>();
200                             // start() arguments which been delivered.
201     final ArrayList<StartItem> pendingStarts = new ArrayList<StartItem>();
202                             // start() arguments that haven't yet been delivered.
203 
dumpStartList(PrintWriter pw, String prefix, List<StartItem> list, long now)204     void dumpStartList(PrintWriter pw, String prefix, List<StartItem> list, long now) {
205         final int N = list.size();
206         for (int i=0; i<N; i++) {
207             StartItem si = list.get(i);
208             pw.print(prefix); pw.print("#"); pw.print(i);
209                     pw.print(" id="); pw.print(si.id);
210                     if (now != 0) {
211                         pw.print(" dur=");
212                         TimeUtils.formatDuration(si.deliveredTime, now, pw);
213                     }
214                     if (si.deliveryCount != 0) {
215                         pw.print(" dc="); pw.print(si.deliveryCount);
216                     }
217                     if (si.doneExecutingCount != 0) {
218                         pw.print(" dxc="); pw.print(si.doneExecutingCount);
219                     }
220                     pw.println("");
221             pw.print(prefix); pw.print("  intent=");
222                     if (si.intent != null) pw.println(si.intent.toString());
223                     else pw.println("null");
224             if (si.neededGrants != null) {
225                 pw.print(prefix); pw.print("  neededGrants=");
226                         pw.println(si.neededGrants);
227             }
228             if (si.uriPermissions != null) {
229                 si.uriPermissions.dump(pw, prefix);
230             }
231         }
232     }
233 
writeToProto(ProtoOutputStream proto, long fieldId)234     void writeToProto(ProtoOutputStream proto, long fieldId) {
235         long token = proto.start(fieldId);
236         proto.write(ServiceRecordProto.SHORT_NAME, this.shortName);
237         proto.write(ServiceRecordProto.IS_RUNNING, app != null);
238         if (app != null) {
239             proto.write(ServiceRecordProto.PID, app.pid);
240         }
241         if (intent != null) {
242             intent.getIntent().writeToProto(proto, ServiceRecordProto.INTENT, false, true, false,
243                     true);
244         }
245         proto.write(ServiceRecordProto.PACKAGE_NAME, packageName);
246         proto.write(ServiceRecordProto.PROCESS_NAME, processName);
247         proto.write(ServiceRecordProto.PERMISSION, permission);
248 
249         long now = SystemClock.uptimeMillis();
250         long nowReal = SystemClock.elapsedRealtime();
251         if (appInfo != null) {
252             long appInfoToken = proto.start(ServiceRecordProto.APPINFO);
253             proto.write(ServiceRecordProto.AppInfo.BASE_DIR, appInfo.sourceDir);
254             if (!Objects.equals(appInfo.sourceDir, appInfo.publicSourceDir)) {
255                 proto.write(ServiceRecordProto.AppInfo.RES_DIR, appInfo.publicSourceDir);
256             }
257             proto.write(ServiceRecordProto.AppInfo.DATA_DIR, appInfo.dataDir);
258             proto.end(appInfoToken);
259         }
260         if (app != null) {
261             app.writeToProto(proto, ServiceRecordProto.APP);
262         }
263         if (isolatedProc != null) {
264             isolatedProc.writeToProto(proto, ServiceRecordProto.ISOLATED_PROC);
265         }
266         proto.write(ServiceRecordProto.WHITELIST_MANAGER, whitelistManager);
267         proto.write(ServiceRecordProto.DELAYED, delayed);
268         if (isForeground || foregroundId != 0) {
269             long fgToken = proto.start(ServiceRecordProto.FOREGROUND);
270             proto.write(ServiceRecordProto.Foreground.ID, foregroundId);
271             foregroundNoti.writeToProto(proto, ServiceRecordProto.Foreground.NOTIFICATION);
272             proto.end(fgToken);
273         }
274         ProtoUtils.toDuration(proto, ServiceRecordProto.CREATE_REAL_TIME, createRealTime, nowReal);
275         ProtoUtils.toDuration(proto,
276                 ServiceRecordProto.STARTING_BG_TIMEOUT, startingBgTimeout, now);
277         ProtoUtils.toDuration(proto, ServiceRecordProto.LAST_ACTIVITY_TIME, lastActivity, now);
278         ProtoUtils.toDuration(proto, ServiceRecordProto.RESTART_TIME, restartTime, now);
279         proto.write(ServiceRecordProto.CREATED_FROM_FG, createdFromFg);
280 
281         if (startRequested || delayedStop || lastStartId != 0) {
282             long startToken = proto.start(ServiceRecordProto.START);
283             proto.write(ServiceRecordProto.Start.START_REQUESTED, startRequested);
284             proto.write(ServiceRecordProto.Start.DELAYED_STOP, delayedStop);
285             proto.write(ServiceRecordProto.Start.STOP_IF_KILLED, stopIfKilled);
286             proto.write(ServiceRecordProto.Start.LAST_START_ID, lastStartId);
287             proto.end(startToken);
288         }
289 
290         if (executeNesting != 0) {
291             long executNestingToken = proto.start(ServiceRecordProto.EXECUTE);
292             proto.write(ServiceRecordProto.ExecuteNesting.EXECUTE_NESTING, executeNesting);
293             proto.write(ServiceRecordProto.ExecuteNesting.EXECUTE_FG, executeFg);
294             ProtoUtils.toDuration(proto,
295                     ServiceRecordProto.ExecuteNesting.EXECUTING_START, executingStart, now);
296             proto.end(executNestingToken);
297         }
298         if (destroying || destroyTime != 0) {
299             ProtoUtils.toDuration(proto, ServiceRecordProto.DESTORY_TIME, destroyTime, now);
300         }
301         if (crashCount != 0 || restartCount != 0 || restartDelay != 0 || nextRestartTime != 0) {
302             long crashToken = proto.start(ServiceRecordProto.CRASH);
303             proto.write(ServiceRecordProto.Crash.RESTART_COUNT, restartCount);
304             ProtoUtils.toDuration(proto, ServiceRecordProto.Crash.RESTART_DELAY, restartDelay, now);
305             ProtoUtils.toDuration(proto,
306                     ServiceRecordProto.Crash.NEXT_RESTART_TIME, nextRestartTime, now);
307             proto.write(ServiceRecordProto.Crash.CRASH_COUNT, crashCount);
308             proto.end(crashToken);
309         }
310 
311         if (deliveredStarts.size() > 0) {
312             final int N = deliveredStarts.size();
313             for (int i = 0; i < N; i++) {
314                 deliveredStarts.get(i).writeToProto(proto,
315                         ServiceRecordProto.DELIVERED_STARTS, now);
316             }
317         }
318         if (pendingStarts.size() > 0) {
319             final int N = pendingStarts.size();
320             for (int i = 0; i < N; i++) {
321                 pendingStarts.get(i).writeToProto(proto, ServiceRecordProto.PENDING_STARTS, now);
322             }
323         }
324         if (bindings.size() > 0) {
325             final int N = bindings.size();
326             for (int i=0; i<N; i++) {
327                 IntentBindRecord b = bindings.valueAt(i);
328                 b.writeToProto(proto, ServiceRecordProto.BINDINGS);
329             }
330         }
331         if (connections.size() > 0) {
332             final int N = connections.size();
333             for (int conni=0; conni<N; conni++) {
334                 ArrayList<ConnectionRecord> c = connections.valueAt(conni);
335                 for (int i=0; i<c.size(); i++) {
336                     c.get(i).writeToProto(proto, ServiceRecordProto.CONNECTIONS);
337                 }
338             }
339         }
340         proto.end(token);
341     }
342 
dump(PrintWriter pw, String prefix)343     void dump(PrintWriter pw, String prefix) {
344         pw.print(prefix); pw.print("intent={");
345                 pw.print(intent.getIntent().toShortString(false, true, false, true));
346                 pw.println('}');
347         pw.print(prefix); pw.print("packageName="); pw.println(packageName);
348         pw.print(prefix); pw.print("processName="); pw.println(processName);
349         if (permission != null) {
350             pw.print(prefix); pw.print("permission="); pw.println(permission);
351         }
352         long now = SystemClock.uptimeMillis();
353         long nowReal = SystemClock.elapsedRealtime();
354         if (appInfo != null) {
355             pw.print(prefix); pw.print("baseDir="); pw.println(appInfo.sourceDir);
356             if (!Objects.equals(appInfo.sourceDir, appInfo.publicSourceDir)) {
357                 pw.print(prefix); pw.print("resDir="); pw.println(appInfo.publicSourceDir);
358             }
359             pw.print(prefix); pw.print("dataDir="); pw.println(appInfo.dataDir);
360         }
361         pw.print(prefix); pw.print("app="); pw.println(app);
362         if (isolatedProc != null) {
363             pw.print(prefix); pw.print("isolatedProc="); pw.println(isolatedProc);
364         }
365         if (whitelistManager) {
366             pw.print(prefix); pw.print("whitelistManager="); pw.println(whitelistManager);
367         }
368         if (delayed) {
369             pw.print(prefix); pw.print("delayed="); pw.println(delayed);
370         }
371         if (isForeground || foregroundId != 0) {
372             pw.print(prefix); pw.print("isForeground="); pw.print(isForeground);
373                     pw.print(" foregroundId="); pw.print(foregroundId);
374                     pw.print(" foregroundNoti="); pw.println(foregroundNoti);
375         }
376         pw.print(prefix); pw.print("createTime=");
377                 TimeUtils.formatDuration(createRealTime, nowReal, pw);
378                 pw.print(" startingBgTimeout=");
379                 TimeUtils.formatDuration(startingBgTimeout, now, pw);
380                 pw.println();
381         pw.print(prefix); pw.print("lastActivity=");
382                 TimeUtils.formatDuration(lastActivity, now, pw);
383                 pw.print(" restartTime=");
384                 TimeUtils.formatDuration(restartTime, now, pw);
385                 pw.print(" createdFromFg="); pw.println(createdFromFg);
386         if (startRequested || delayedStop || lastStartId != 0) {
387             pw.print(prefix); pw.print("startRequested="); pw.print(startRequested);
388                     pw.print(" delayedStop="); pw.print(delayedStop);
389                     pw.print(" stopIfKilled="); pw.print(stopIfKilled);
390                     pw.print(" callStart="); pw.print(callStart);
391                     pw.print(" lastStartId="); pw.println(lastStartId);
392         }
393         if (executeNesting != 0) {
394             pw.print(prefix); pw.print("executeNesting="); pw.print(executeNesting);
395                     pw.print(" executeFg="); pw.print(executeFg);
396                     pw.print(" executingStart=");
397                     TimeUtils.formatDuration(executingStart, now, pw);
398                     pw.println();
399         }
400         if (destroying || destroyTime != 0) {
401             pw.print(prefix); pw.print("destroying="); pw.print(destroying);
402                     pw.print(" destroyTime=");
403                     TimeUtils.formatDuration(destroyTime, now, pw);
404                     pw.println();
405         }
406         if (crashCount != 0 || restartCount != 0
407                 || restartDelay != 0 || nextRestartTime != 0) {
408             pw.print(prefix); pw.print("restartCount="); pw.print(restartCount);
409                     pw.print(" restartDelay=");
410                     TimeUtils.formatDuration(restartDelay, now, pw);
411                     pw.print(" nextRestartTime=");
412                     TimeUtils.formatDuration(nextRestartTime, now, pw);
413                     pw.print(" crashCount="); pw.println(crashCount);
414         }
415         if (deliveredStarts.size() > 0) {
416             pw.print(prefix); pw.println("Delivered Starts:");
417             dumpStartList(pw, prefix, deliveredStarts, now);
418         }
419         if (pendingStarts.size() > 0) {
420             pw.print(prefix); pw.println("Pending Starts:");
421             dumpStartList(pw, prefix, pendingStarts, 0);
422         }
423         if (bindings.size() > 0) {
424             pw.print(prefix); pw.println("Bindings:");
425             for (int i=0; i<bindings.size(); i++) {
426                 IntentBindRecord b = bindings.valueAt(i);
427                 pw.print(prefix); pw.print("* IntentBindRecord{");
428                         pw.print(Integer.toHexString(System.identityHashCode(b)));
429                         if ((b.collectFlags()&Context.BIND_AUTO_CREATE) != 0) {
430                             pw.append(" CREATE");
431                         }
432                         pw.println("}:");
433                 b.dumpInService(pw, prefix + "  ");
434             }
435         }
436         if (connections.size() > 0) {
437             pw.print(prefix); pw.println("All Connections:");
438             for (int conni=0; conni<connections.size(); conni++) {
439                 ArrayList<ConnectionRecord> c = connections.valueAt(conni);
440                 for (int i=0; i<c.size(); i++) {
441                     pw.print(prefix); pw.print("  "); pw.println(c.get(i));
442                 }
443             }
444         }
445     }
446 
ServiceRecord(ActivityManagerService ams, BatteryStatsImpl.Uid.Pkg.Serv servStats, ComponentName name, Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg, Runnable restarter)447     ServiceRecord(ActivityManagerService ams,
448             BatteryStatsImpl.Uid.Pkg.Serv servStats, ComponentName name,
449             Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg,
450             Runnable restarter) {
451         this.ams = ams;
452         this.stats = servStats;
453         this.name = name;
454         shortName = name.flattenToShortString();
455         this.intent = intent;
456         serviceInfo = sInfo;
457         appInfo = sInfo.applicationInfo;
458         packageName = sInfo.applicationInfo.packageName;
459         processName = sInfo.processName;
460         permission = sInfo.permission;
461         exported = sInfo.exported;
462         this.restarter = restarter;
463         createRealTime = SystemClock.elapsedRealtime();
464         lastActivity = SystemClock.uptimeMillis();
465         userId = UserHandle.getUserId(appInfo.uid);
466         createdFromFg = callerIsFg;
467     }
468 
getTracker()469     public ServiceState getTracker() {
470         if (tracker != null) {
471             return tracker;
472         }
473         if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
474             tracker = ams.mProcessStats.getServiceStateLocked(serviceInfo.packageName,
475                     serviceInfo.applicationInfo.uid, serviceInfo.applicationInfo.versionCode,
476                     serviceInfo.processName, serviceInfo.name);
477             tracker.applyNewOwner(this);
478         }
479         return tracker;
480     }
481 
forceClearTracker()482     public void forceClearTracker() {
483         if (tracker != null) {
484             tracker.clearCurrentOwner(this, true);
485             tracker = null;
486         }
487     }
488 
makeRestarting(int memFactor, long now)489     public void makeRestarting(int memFactor, long now) {
490         if (restartTracker == null) {
491             if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) {
492                 restartTracker = ams.mProcessStats.getServiceStateLocked(serviceInfo.packageName,
493                         serviceInfo.applicationInfo.uid, serviceInfo.applicationInfo.versionCode,
494                         serviceInfo.processName, serviceInfo.name);
495             }
496             if (restartTracker == null) {
497                 return;
498             }
499         }
500         restartTracker.setRestarting(true, memFactor, now);
501     }
502 
retrieveAppBindingLocked(Intent intent, ProcessRecord app)503     public AppBindRecord retrieveAppBindingLocked(Intent intent,
504             ProcessRecord app) {
505         Intent.FilterComparison filter = new Intent.FilterComparison(intent);
506         IntentBindRecord i = bindings.get(filter);
507         if (i == null) {
508             i = new IntentBindRecord(this, filter);
509             bindings.put(filter, i);
510         }
511         AppBindRecord a = i.apps.get(app);
512         if (a != null) {
513             return a;
514         }
515         a = new AppBindRecord(this, i, app);
516         i.apps.put(app, a);
517         return a;
518     }
519 
hasAutoCreateConnections()520     public boolean hasAutoCreateConnections() {
521         // XXX should probably keep a count of the number of auto-create
522         // connections directly in the service.
523         for (int conni=connections.size()-1; conni>=0; conni--) {
524             ArrayList<ConnectionRecord> cr = connections.valueAt(conni);
525             for (int i=0; i<cr.size(); i++) {
526                 if ((cr.get(i).flags&Context.BIND_AUTO_CREATE) != 0) {
527                     return true;
528                 }
529             }
530         }
531         return false;
532     }
533 
updateWhitelistManager()534     public void updateWhitelistManager() {
535         whitelistManager = false;
536         for (int conni=connections.size()-1; conni>=0; conni--) {
537             ArrayList<ConnectionRecord> cr = connections.valueAt(conni);
538             for (int i=0; i<cr.size(); i++) {
539                 if ((cr.get(i).flags&Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
540                     whitelistManager = true;
541                     return;
542                 }
543             }
544         }
545     }
546 
resetRestartCounter()547     public void resetRestartCounter() {
548         restartCount = 0;
549         restartDelay = 0;
550         restartTime = 0;
551     }
552 
findDeliveredStart(int id, boolean taskRemoved, boolean remove)553     public StartItem findDeliveredStart(int id, boolean taskRemoved, boolean remove) {
554         final int N = deliveredStarts.size();
555         for (int i=0; i<N; i++) {
556             StartItem si = deliveredStarts.get(i);
557             if (si.id == id && si.taskRemoved == taskRemoved) {
558                 if (remove) deliveredStarts.remove(i);
559                 return si;
560             }
561         }
562 
563         return null;
564     }
565 
getLastStartId()566     public int getLastStartId() {
567         return lastStartId;
568     }
569 
makeNextStartId()570     public int makeNextStartId() {
571         lastStartId++;
572         if (lastStartId < 1) {
573             lastStartId = 1;
574         }
575         return lastStartId;
576     }
577 
postNotification()578     public void postNotification() {
579         final int appUid = appInfo.uid;
580         final int appPid = app.pid;
581         if (foregroundId != 0 && foregroundNoti != null) {
582             // Do asynchronous communication with notification manager to
583             // avoid deadlocks.
584             final String localPackageName = packageName;
585             final int localForegroundId = foregroundId;
586             final Notification _foregroundNoti = foregroundNoti;
587             final ServiceRecord record = this;
588             ams.mHandler.post(new Runnable() {
589                 public void run() {
590                     NotificationManagerInternal nm = LocalServices.getService(
591                             NotificationManagerInternal.class);
592                     if (nm == null) {
593                         return;
594                     }
595                     Notification localForegroundNoti = _foregroundNoti;
596                     try {
597                         if (localForegroundNoti.getSmallIcon() == null) {
598                             // It is not correct for the caller to not supply a notification
599                             // icon, but this used to be able to slip through, so for
600                             // those dirty apps we will create a notification clearly
601                             // blaming the app.
602                             Slog.v(TAG, "Attempted to start a foreground service ("
603                                     + name
604                                     + ") with a broken notification (no icon: "
605                                     + localForegroundNoti
606                                     + ")");
607 
608                             CharSequence appName = appInfo.loadLabel(
609                                     ams.mContext.getPackageManager());
610                             if (appName == null) {
611                                 appName = appInfo.packageName;
612                             }
613                             Context ctx = null;
614                             try {
615                                 ctx = ams.mContext.createPackageContextAsUser(
616                                         appInfo.packageName, 0, new UserHandle(userId));
617 
618                                 Notification.Builder notiBuilder = new Notification.Builder(ctx,
619                                         localForegroundNoti.getChannelId());
620 
621                                 // it's ugly, but it clearly identifies the app
622                                 notiBuilder.setSmallIcon(appInfo.icon);
623 
624                                 // mark as foreground
625                                 notiBuilder.setFlag(Notification.FLAG_FOREGROUND_SERVICE, true);
626 
627                                 Intent runningIntent = new Intent(
628                                         Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
629                                 runningIntent.setData(Uri.fromParts("package",
630                                         appInfo.packageName, null));
631                                 PendingIntent pi = PendingIntent.getActivityAsUser(ams.mContext, 0,
632                                         runningIntent, PendingIntent.FLAG_UPDATE_CURRENT, null,
633                                         UserHandle.of(userId));
634                                 notiBuilder.setColor(ams.mContext.getColor(
635                                         com.android.internal
636                                                 .R.color.system_notification_accent_color));
637                                 notiBuilder.setContentTitle(
638                                         ams.mContext.getString(
639                                                 com.android.internal.R.string
640                                                         .app_running_notification_title,
641                                                 appName));
642                                 notiBuilder.setContentText(
643                                         ams.mContext.getString(
644                                                 com.android.internal.R.string
645                                                         .app_running_notification_text,
646                                                 appName));
647                                 notiBuilder.setContentIntent(pi);
648 
649                                 localForegroundNoti = notiBuilder.build();
650                             } catch (PackageManager.NameNotFoundException e) {
651                             }
652                         }
653                         if (nm.getNotificationChannel(localPackageName, appUid,
654                                 localForegroundNoti.getChannelId()) == null) {
655                             int targetSdkVersion = Build.VERSION_CODES.O_MR1;
656                             try {
657                                 final ApplicationInfo applicationInfo =
658                                         ams.mContext.getPackageManager().getApplicationInfoAsUser(
659                                                 appInfo.packageName, 0, userId);
660                                 targetSdkVersion = applicationInfo.targetSdkVersion;
661                             } catch (PackageManager.NameNotFoundException e) {
662                             }
663                             if (targetSdkVersion >= Build.VERSION_CODES.O_MR1) {
664                                 throw new RuntimeException(
665                                         "invalid channel for service notification: "
666                                                 + foregroundNoti);
667                             }
668                         }
669                         if (localForegroundNoti.getSmallIcon() == null) {
670                             // Notifications whose icon is 0 are defined to not show
671                             // a notification, silently ignoring it.  We don't want to
672                             // just ignore it, we want to prevent the service from
673                             // being foreground.
674                             throw new RuntimeException("invalid service notification: "
675                                     + foregroundNoti);
676                         }
677                         nm.enqueueNotification(localPackageName, localPackageName,
678                                 appUid, appPid, null, localForegroundId, localForegroundNoti,
679                                 userId);
680 
681                         foregroundNoti = localForegroundNoti; // save it for amending next time
682                     } catch (RuntimeException e) {
683                         Slog.w(TAG, "Error showing notification for service", e);
684                         // If it gave us a garbage notification, it doesn't
685                         // get to be foreground.
686                         ams.mServices.killMisbehavingService(record,
687                                 appUid, appPid, localPackageName);
688                     }
689                 }
690             });
691         }
692     }
693 
cancelNotification()694     public void cancelNotification() {
695         // Do asynchronous communication with notification manager to
696         // avoid deadlocks.
697         final String localPackageName = packageName;
698         final int localForegroundId = foregroundId;
699         ams.mHandler.post(new Runnable() {
700             public void run() {
701                 INotificationManager inm = NotificationManager.getService();
702                 if (inm == null) {
703                     return;
704                 }
705                 try {
706                     inm.cancelNotificationWithTag(localPackageName, null,
707                             localForegroundId, userId);
708                 } catch (RuntimeException e) {
709                     Slog.w(TAG, "Error canceling notification for service", e);
710                 } catch (RemoteException e) {
711                 }
712             }
713         });
714     }
715 
stripForegroundServiceFlagFromNotification()716     public void stripForegroundServiceFlagFromNotification() {
717         if (foregroundId == 0) {
718             return;
719         }
720 
721         final int localForegroundId = foregroundId;
722         final int localUserId = userId;
723         final String localPackageName = packageName;
724 
725         // Do asynchronous communication with notification manager to
726         // avoid deadlocks.
727         ams.mHandler.post(new Runnable() {
728             @Override
729             public void run() {
730                 NotificationManagerInternal nmi = LocalServices.getService(
731                         NotificationManagerInternal.class);
732                 if (nmi == null) {
733                     return;
734                 }
735                 nmi.removeForegroundServiceFlagFromNotification(localPackageName, localForegroundId,
736                         localUserId);
737             }
738         });
739     }
740 
clearDeliveredStartsLocked()741     public void clearDeliveredStartsLocked() {
742         for (int i=deliveredStarts.size()-1; i>=0; i--) {
743             deliveredStarts.get(i).removeUriPermissionsLocked();
744         }
745         deliveredStarts.clear();
746     }
747 
toString()748     public String toString() {
749         if (stringName != null) {
750             return stringName;
751         }
752         StringBuilder sb = new StringBuilder(128);
753         sb.append("ServiceRecord{")
754             .append(Integer.toHexString(System.identityHashCode(this)))
755             .append(" u").append(userId)
756             .append(' ').append(shortName).append('}');
757         return stringName = sb.toString();
758     }
759 
getComponentName()760     public ComponentName getComponentName() {
761         return name;
762     }
763 }
764