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             ams.mHandler.post(new Runnable() {
588                 public void run() {
589                     NotificationManagerInternal nm = LocalServices.getService(
590                             NotificationManagerInternal.class);
591                     if (nm == null) {
592                         return;
593                     }
594                     Notification localForegroundNoti = _foregroundNoti;
595                     try {
596                         if (localForegroundNoti.getSmallIcon() == null) {
597                             // It is not correct for the caller to not supply a notification
598                             // icon, but this used to be able to slip through, so for
599                             // those dirty apps we will create a notification clearly
600                             // blaming the app.
601                             Slog.v(TAG, "Attempted to start a foreground service ("
602                                     + name
603                                     + ") with a broken notification (no icon: "
604                                     + localForegroundNoti
605                                     + ")");
606 
607                             CharSequence appName = appInfo.loadLabel(
608                                     ams.mContext.getPackageManager());
609                             if (appName == null) {
610                                 appName = appInfo.packageName;
611                             }
612                             Context ctx = null;
613                             try {
614                                 ctx = ams.mContext.createPackageContextAsUser(
615                                         appInfo.packageName, 0, new UserHandle(userId));
616 
617                                 Notification.Builder notiBuilder = new Notification.Builder(ctx,
618                                         localForegroundNoti.getChannelId());
619 
620                                 // it's ugly, but it clearly identifies the app
621                                 notiBuilder.setSmallIcon(appInfo.icon);
622 
623                                 // mark as foreground
624                                 notiBuilder.setFlag(Notification.FLAG_FOREGROUND_SERVICE, true);
625 
626                                 Intent runningIntent = new Intent(
627                                         Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
628                                 runningIntent.setData(Uri.fromParts("package",
629                                         appInfo.packageName, null));
630                                 PendingIntent pi = PendingIntent.getActivityAsUser(ams.mContext, 0,
631                                         runningIntent, PendingIntent.FLAG_UPDATE_CURRENT, null,
632                                         UserHandle.of(userId));
633                                 notiBuilder.setColor(ams.mContext.getColor(
634                                         com.android.internal
635                                                 .R.color.system_notification_accent_color));
636                                 notiBuilder.setContentTitle(
637                                         ams.mContext.getString(
638                                                 com.android.internal.R.string
639                                                         .app_running_notification_title,
640                                                 appName));
641                                 notiBuilder.setContentText(
642                                         ams.mContext.getString(
643                                                 com.android.internal.R.string
644                                                         .app_running_notification_text,
645                                                 appName));
646                                 notiBuilder.setContentIntent(pi);
647 
648                                 localForegroundNoti = notiBuilder.build();
649                             } catch (PackageManager.NameNotFoundException e) {
650                             }
651                         }
652                         if (nm.getNotificationChannel(localPackageName, appUid,
653                                 localForegroundNoti.getChannelId()) == null) {
654                             int targetSdkVersion = Build.VERSION_CODES.O_MR1;
655                             try {
656                                 final ApplicationInfo applicationInfo =
657                                         ams.mContext.getPackageManager().getApplicationInfoAsUser(
658                                                 appInfo.packageName, 0, userId);
659                                 targetSdkVersion = applicationInfo.targetSdkVersion;
660                             } catch (PackageManager.NameNotFoundException e) {
661                             }
662                             if (targetSdkVersion >= Build.VERSION_CODES.O_MR1) {
663                                 throw new RuntimeException(
664                                         "invalid channel for service notification: "
665                                                 + foregroundNoti);
666                             }
667                         }
668                         if (localForegroundNoti.getSmallIcon() == null) {
669                             // Notifications whose icon is 0 are defined to not show
670                             // a notification, silently ignoring it.  We don't want to
671                             // just ignore it, we want to prevent the service from
672                             // being foreground.
673                             throw new RuntimeException("invalid service notification: "
674                                     + foregroundNoti);
675                         }
676                         nm.enqueueNotification(localPackageName, localPackageName,
677                                 appUid, appPid, null, localForegroundId, localForegroundNoti,
678                                 userId);
679 
680                         foregroundNoti = localForegroundNoti; // save it for amending next time
681                     } catch (RuntimeException e) {
682                         Slog.w(TAG, "Error showing notification for service", e);
683                         // If it gave us a garbage notification, it doesn't
684                         // get to be foreground.
685                         ams.setServiceForeground(name, ServiceRecord.this,
686                                 0, null, 0);
687                         ams.crashApplication(appUid, appPid, localPackageName, -1,
688                                 "Bad notification for startForeground: " + e);
689                     }
690                 }
691             });
692         }
693     }
694 
cancelNotification()695     public void cancelNotification() {
696         // Do asynchronous communication with notification manager to
697         // avoid deadlocks.
698         final String localPackageName = packageName;
699         final int localForegroundId = foregroundId;
700         ams.mHandler.post(new Runnable() {
701             public void run() {
702                 INotificationManager inm = NotificationManager.getService();
703                 if (inm == null) {
704                     return;
705                 }
706                 try {
707                     inm.cancelNotificationWithTag(localPackageName, null,
708                             localForegroundId, userId);
709                 } catch (RuntimeException e) {
710                     Slog.w(TAG, "Error canceling notification for service", e);
711                 } catch (RemoteException e) {
712                 }
713             }
714         });
715     }
716 
stripForegroundServiceFlagFromNotification()717     public void stripForegroundServiceFlagFromNotification() {
718         if (foregroundId == 0) {
719             return;
720         }
721 
722         final int localForegroundId = foregroundId;
723         final int localUserId = userId;
724         final String localPackageName = packageName;
725 
726         // Do asynchronous communication with notification manager to
727         // avoid deadlocks.
728         ams.mHandler.post(new Runnable() {
729             @Override
730             public void run() {
731                 NotificationManagerInternal nmi = LocalServices.getService(
732                         NotificationManagerInternal.class);
733                 if (nmi == null) {
734                     return;
735                 }
736                 nmi.removeForegroundServiceFlagFromNotification(localPackageName, localForegroundId,
737                         localUserId);
738             }
739         });
740     }
741 
clearDeliveredStartsLocked()742     public void clearDeliveredStartsLocked() {
743         for (int i=deliveredStarts.size()-1; i>=0; i--) {
744             deliveredStarts.get(i).removeUriPermissionsLocked();
745         }
746         deliveredStarts.clear();
747     }
748 
toString()749     public String toString() {
750         if (stringName != null) {
751             return stringName;
752         }
753         StringBuilder sb = new StringBuilder(128);
754         sb.append("ServiceRecord{")
755             .append(Integer.toHexString(System.identityHashCode(this)))
756             .append(" u").append(userId)
757             .append(' ').append(shortName).append('}');
758         return stringName = sb.toString();
759     }
760 
getComponentName()761     public ComponentName getComponentName() {
762         return name;
763     }
764 }
765