The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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 | |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 19 | import com.android.internal.app.procstats.ServiceState; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 20 | import com.android.internal.os.BatteryStatsImpl; |
Adam Lesinski | 182f73f | 2013-12-05 16:48:06 -0800 | [diff] [blame] | 21 | import com.android.server.LocalServices; |
| 22 | import com.android.server.notification.NotificationManagerInternal; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 23 | |
Dianne Hackborn | d8a43f6 | 2009-08-17 23:33:56 -0700 | [diff] [blame] | 24 | import android.app.INotificationManager; |
| 25 | import android.app.Notification; |
| 26 | import android.app.NotificationManager; |
Dianne Hackborn | 390517b | 2013-05-30 15:03:32 -0700 | [diff] [blame] | 27 | import android.app.PendingIntent; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 28 | import android.content.ComponentName; |
Dianne Hackborn | 0c38049 | 2012-08-20 17:23:30 -0700 | [diff] [blame] | 29 | import android.content.Context; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 30 | import android.content.Intent; |
| 31 | import android.content.pm.ApplicationInfo; |
Amith Yamasani | 742a671 | 2011-05-04 14:49:28 -0700 | [diff] [blame] | 32 | import android.content.pm.PackageManager; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 33 | import android.content.pm.ServiceInfo; |
Dianne Hackborn | 390517b | 2013-05-30 15:03:32 -0700 | [diff] [blame] | 34 | import android.net.Uri; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 35 | import android.os.Binder; |
Julia Reynolds | 5a4399a | 2017-10-11 08:44:46 -0400 | [diff] [blame] | 36 | import android.os.Build; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 37 | import android.os.IBinder; |
Dianne Hackborn | d8a43f6 | 2009-08-17 23:33:56 -0700 | [diff] [blame] | 38 | import android.os.RemoteException; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 39 | import android.os.SystemClock; |
Dianne Hackborn | f02b60a | 2012-08-16 10:48:27 -0700 | [diff] [blame] | 40 | import android.os.UserHandle; |
Dianne Hackborn | 390517b | 2013-05-30 15:03:32 -0700 | [diff] [blame] | 41 | import android.provider.Settings; |
| 42 | import android.util.ArrayMap; |
Joe Onorato | 8a9b220 | 2010-02-26 18:56:32 -0800 | [diff] [blame] | 43 | import android.util.Slog; |
Dianne Hackborn | 1ebccf5 | 2010-08-15 13:04:34 -0700 | [diff] [blame] | 44 | import android.util.TimeUtils; |
Yi Jin | 6b51414 | 2017-10-30 14:54:12 -0700 | [diff] [blame] | 45 | import android.util.proto.ProtoOutputStream; |
| 46 | import android.util.proto.ProtoUtils; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 47 | |
| 48 | import java.io.PrintWriter; |
| 49 | import java.util.ArrayList; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 50 | import java.util.List; |
Jeff Sharkey | 8a4c972 | 2014-06-16 13:48:42 -0700 | [diff] [blame] | 51 | import java.util.Objects; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 52 | |
Wale Ogunwale | e23149f | 2015-03-06 15:39:44 -0800 | [diff] [blame] | 53 | import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM; |
| 54 | import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME; |
| 55 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 56 | /** |
| 57 | * A running application service. |
| 58 | */ |
Dianne Hackborn | be4e6aa | 2013-06-07 13:25:29 -0700 | [diff] [blame] | 59 | final class ServiceRecord extends Binder { |
Wale Ogunwale | e23149f | 2015-03-06 15:39:44 -0800 | [diff] [blame] | 60 | private static final String TAG = TAG_WITH_CLASS_NAME ? "ServiceRecord" : TAG_AM; |
| 61 | |
Dianne Hackborn | 39792d2 | 2010-08-19 18:01:52 -0700 | [diff] [blame] | 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 | |
Dianne Hackborn | b1c4a2a | 2010-01-19 15:36:42 -0800 | [diff] [blame] | 68 | final ActivityManagerService ams; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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 | final ApplicationInfo appInfo; |
| 77 | // information about service's app. |
Amith Yamasani | 742a671 | 2011-05-04 14:49:28 -0700 | [diff] [blame] | 78 | final int userId; // user that this service is running as |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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 |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 82 | final boolean exported; // from ServiceInfo.exported |
| 83 | final Runnable restarter; // used to schedule retries of starting the service |
Yi Jin | 6b51414 | 2017-10-30 14:54:12 -0700 | [diff] [blame] | 84 | final long createRealTime; // when this service was created |
Dianne Hackborn | 390517b | 2013-05-30 15:03:32 -0700 | [diff] [blame] | 85 | final ArrayMap<Intent.FilterComparison, IntentBindRecord> bindings |
| 86 | = new ArrayMap<Intent.FilterComparison, IntentBindRecord>(); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 87 | // All active bindings to the service. |
Dianne Hackborn | 390517b | 2013-05-30 15:03:32 -0700 | [diff] [blame] | 88 | final ArrayMap<IBinder, ArrayList<ConnectionRecord>> connections |
| 89 | = new ArrayMap<IBinder, ArrayList<ConnectionRecord>>(); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 90 | // IBinder -> ConnectionRecord of all bound clients |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 91 | |
Dianne Hackborn | d8a43f6 | 2009-08-17 23:33:56 -0700 | [diff] [blame] | 92 | ProcessRecord app; // where this service is running or null. |
Dianne Hackborn | a0c283e | 2012-02-09 10:47:01 -0800 | [diff] [blame] | 93 | ProcessRecord isolatedProc; // keep track of isolated process, if requested |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 94 | ServiceState tracker; // tracking service execution, may be null |
| 95 | ServiceState restartTracker; // tracking service restart |
Dianne Hackborn | a590d2b | 2016-06-27 15:07:18 -0700 | [diff] [blame] | 96 | boolean whitelistManager; // any bindings to this service have BIND_ALLOW_WHITELIST_MANAGEMENT? |
Dianne Hackborn | 9210bc8 | 2013-09-05 12:31:16 -0700 | [diff] [blame] | 97 | boolean delayed; // are we waiting to start this service in the background? |
Christopher Tate | 08992ac | 2017-03-21 11:37:06 -0700 | [diff] [blame] | 98 | boolean fgRequired; // is the service required to go foreground after starting? |
| 99 | boolean fgWaiting; // is a timeout for going foreground already scheduled? |
Dianne Hackborn | d8a43f6 | 2009-08-17 23:33:56 -0700 | [diff] [blame] | 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. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 103 | long lastActivity; // last time there was some activity on the service. |
Dianne Hackborn | 9210bc8 | 2013-09-05 12:31:16 -0700 | [diff] [blame] | 104 | long startingBgTimeout; // time at which we scheduled this for a delayed start. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 105 | boolean startRequested; // someone explicitly called start? |
Dianne Hackborn | 9210bc8 | 2013-09-05 12:31:16 -0700 | [diff] [blame] | 106 | boolean delayedStop; // service has been stopped but is in a delayed start? |
Dianne Hackborn | f6f9f2d | 2009-08-21 16:26:03 -0700 | [diff] [blame] | 107 | boolean stopIfKilled; // last onStart() said to stop if service killed? |
Yi Jin | 6b51414 | 2017-10-30 14:54:12 -0700 | [diff] [blame] | 108 | boolean callStart; // last onStart() has asked to always be called on restart. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 109 | int executeNesting; // number of outstanding operations keeping foreground. |
Dianne Hackborn | bf36ee2 | 2013-07-26 18:24:10 -0700 | [diff] [blame] | 110 | boolean executeFg; // should we be executing in the foreground? |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 111 | long executingStart; // start time of last execute request. |
Dianne Hackborn | bf36ee2 | 2013-07-26 18:24:10 -0700 | [diff] [blame] | 112 | boolean createdFromFg; // was this service last created due to a foreground process call? |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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. |
Dianne Hackborn | 455625e | 2015-01-21 09:55:13 -0800 | [diff] [blame] | 119 | boolean destroying; // set when we have started destroying the service |
Craig Mautner | 66c4a82 | 2015-01-16 12:48:16 -0800 | [diff] [blame] | 120 | long destroyTime; // time at which destory was initiated. |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 121 | |
Dianne Hackborn | f210d6b | 2009-04-13 18:42:49 -0700 | [diff] [blame] | 122 | String stringName; // caching of toString |
Geoffrey Pitsch | af759c5 | 2017-02-15 09:35:38 -0500 | [diff] [blame] | 123 | |
Dianne Hackborn | 0c5001d | 2011-04-12 18:16:08 -0700 | [diff] [blame] | 124 | private int lastStartId; // identifier of most recent start request. |
| 125 | |
Dianne Hackborn | 7e26964 | 2010-08-25 19:50:20 -0700 | [diff] [blame] | 126 | static class StartItem { |
Dianne Hackborn | 39792d2 | 2010-08-19 18:01:52 -0700 | [diff] [blame] | 127 | final ServiceRecord sr; |
Dianne Hackborn | 0c5001d | 2011-04-12 18:16:08 -0700 | [diff] [blame] | 128 | final boolean taskRemoved; |
Dianne Hackborn | 39792d2 | 2010-08-19 18:01:52 -0700 | [diff] [blame] | 129 | final int id; |
Todd Kennedy | 51b3aac | 2017-03-30 17:50:42 -0700 | [diff] [blame] | 130 | final int callingId; |
Dianne Hackborn | 39792d2 | 2010-08-19 18:01:52 -0700 | [diff] [blame] | 131 | final Intent intent; |
Dianne Hackborn | 21c241e | 2012-03-08 13:57:23 -0800 | [diff] [blame] | 132 | final ActivityManagerService.NeededUriGrants neededGrants; |
Dianne Hackborn | 39792d2 | 2010-08-19 18:01:52 -0700 | [diff] [blame] | 133 | long deliveredTime; |
| 134 | int deliveryCount; |
| 135 | int doneExecutingCount; |
Dianne Hackborn | 7e26964 | 2010-08-25 19:50:20 -0700 | [diff] [blame] | 136 | UriPermissionOwner uriPermissions; |
Dianne Hackborn | 39792d2 | 2010-08-19 18:01:52 -0700 | [diff] [blame] | 137 | |
| 138 | String stringName; // caching of toString |
| 139 | |
Dianne Hackborn | 0c5001d | 2011-04-12 18:16:08 -0700 | [diff] [blame] | 140 | StartItem(ServiceRecord _sr, boolean _taskRemoved, int _id, Intent _intent, |
Todd Kennedy | 51b3aac | 2017-03-30 17:50:42 -0700 | [diff] [blame] | 141 | ActivityManagerService.NeededUriGrants _neededGrants, int _callingId) { |
Dianne Hackborn | 39792d2 | 2010-08-19 18:01:52 -0700 | [diff] [blame] | 142 | sr = _sr; |
Dianne Hackborn | 0c5001d | 2011-04-12 18:16:08 -0700 | [diff] [blame] | 143 | taskRemoved = _taskRemoved; |
Dianne Hackborn | 39792d2 | 2010-08-19 18:01:52 -0700 | [diff] [blame] | 144 | id = _id; |
| 145 | intent = _intent; |
Dianne Hackborn | 21c241e | 2012-03-08 13:57:23 -0800 | [diff] [blame] | 146 | neededGrants = _neededGrants; |
Todd Kennedy | 51b3aac | 2017-03-30 17:50:42 -0700 | [diff] [blame] | 147 | callingId = _callingId; |
Dianne Hackborn | 39792d2 | 2010-08-19 18:01:52 -0700 | [diff] [blame] | 148 | } |
| 149 | |
Dianne Hackborn | 7e26964 | 2010-08-25 19:50:20 -0700 | [diff] [blame] | 150 | UriPermissionOwner getUriPermissionsLocked() { |
| 151 | if (uriPermissions == null) { |
| 152 | uriPermissions = new UriPermissionOwner(sr.ams, this); |
| 153 | } |
| 154 | return uriPermissions; |
| 155 | } |
| 156 | |
Dianne Hackborn | 39792d2 | 2010-08-19 18:01:52 -0700 | [diff] [blame] | 157 | void removeUriPermissionsLocked() { |
Dianne Hackborn | 7e26964 | 2010-08-25 19:50:20 -0700 | [diff] [blame] | 158 | if (uriPermissions != null) { |
| 159 | uriPermissions.removeUriPermissionsLocked(); |
| 160 | uriPermissions = null; |
Dianne Hackborn | 39792d2 | 2010-08-19 18:01:52 -0700 | [diff] [blame] | 161 | } |
| 162 | } |
| 163 | |
Yi Jin | 6b51414 | 2017-10-30 14:54:12 -0700 | [diff] [blame] | 164 | public void writeToProto(ProtoOutputStream proto, long fieldId, long now) { |
| 165 | long token = proto.start(fieldId); |
Yi Jin | 163967f | 2018-03-15 13:49:44 -0700 | [diff] [blame] | 166 | proto.write(ServiceRecordProto.StartItem.ID, id); |
Yi Jin | 6b51414 | 2017-10-30 14:54:12 -0700 | [diff] [blame] | 167 | ProtoUtils.toDuration(proto, |
Yi Jin | 163967f | 2018-03-15 13:49:44 -0700 | [diff] [blame] | 168 | ServiceRecordProto.StartItem.DURATION, deliveredTime, now); |
| 169 | proto.write(ServiceRecordProto.StartItem.DELIVERY_COUNT, deliveryCount); |
| 170 | proto.write(ServiceRecordProto.StartItem.DONE_EXECUTING_COUNT, doneExecutingCount); |
Yi Jin | 6b51414 | 2017-10-30 14:54:12 -0700 | [diff] [blame] | 171 | if (intent != null) { |
Yi Jin | 163967f | 2018-03-15 13:49:44 -0700 | [diff] [blame] | 172 | intent.writeToProto(proto, ServiceRecordProto.StartItem.INTENT, true, true, |
Yi Jin | 6b51414 | 2017-10-30 14:54:12 -0700 | [diff] [blame] | 173 | true, false); |
| 174 | } |
| 175 | if (neededGrants != null) { |
Yi Jin | 163967f | 2018-03-15 13:49:44 -0700 | [diff] [blame] | 176 | neededGrants.writeToProto(proto, ServiceRecordProto.StartItem.NEEDED_GRANTS); |
Yi Jin | 6b51414 | 2017-10-30 14:54:12 -0700 | [diff] [blame] | 177 | } |
| 178 | if (uriPermissions != null) { |
Yi Jin | 163967f | 2018-03-15 13:49:44 -0700 | [diff] [blame] | 179 | uriPermissions.writeToProto(proto, ServiceRecordProto.StartItem.URI_PERMISSIONS); |
Yi Jin | 6b51414 | 2017-10-30 14:54:12 -0700 | [diff] [blame] | 180 | } |
| 181 | proto.end(token); |
| 182 | } |
| 183 | |
Dianne Hackborn | 39792d2 | 2010-08-19 18:01:52 -0700 | [diff] [blame] | 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 | |
Dianne Hackborn | f6f9f2d | 2009-08-21 16:26:03 -0700 | [diff] [blame] | 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); |
Dianne Hackborn | 1ebccf5 | 2010-08-15 13:04:34 -0700 | [diff] [blame] | 210 | if (now != 0) { |
| 211 | pw.print(" dur="); |
| 212 | TimeUtils.formatDuration(si.deliveredTime, now, pw); |
| 213 | } |
Dianne Hackborn | f6f9f2d | 2009-08-21 16:26:03 -0700 | [diff] [blame] | 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 | } |
Dianne Hackborn | 39792d2 | 2010-08-19 18:01:52 -0700 | [diff] [blame] | 220 | pw.println(""); |
| 221 | pw.print(prefix); pw.print(" intent="); |
Dianne Hackborn | f6f9f2d | 2009-08-21 16:26:03 -0700 | [diff] [blame] | 222 | if (si.intent != null) pw.println(si.intent.toString()); |
| 223 | else pw.println("null"); |
Dianne Hackborn | 21c241e | 2012-03-08 13:57:23 -0800 | [diff] [blame] | 224 | if (si.neededGrants != null) { |
| 225 | pw.print(prefix); pw.print(" neededGrants="); |
| 226 | pw.println(si.neededGrants); |
Dianne Hackborn | 39792d2 | 2010-08-19 18:01:52 -0700 | [diff] [blame] | 227 | } |
Dianne Hackborn | 7e26964 | 2010-08-25 19:50:20 -0700 | [diff] [blame] | 228 | if (si.uriPermissions != null) { |
Jeff Sharkey | 846318a | 2014-04-04 12:12:41 -0700 | [diff] [blame] | 229 | si.uriPermissions.dump(pw, prefix); |
Dianne Hackborn | 39792d2 | 2010-08-19 18:01:52 -0700 | [diff] [blame] | 230 | } |
Dianne Hackborn | f6f9f2d | 2009-08-21 16:26:03 -0700 | [diff] [blame] | 231 | } |
| 232 | } |
Geoffrey Pitsch | af759c5 | 2017-02-15 09:35:38 -0500 | [diff] [blame] | 233 | |
Yi Jin | 6b51414 | 2017-10-30 14:54:12 -0700 | [diff] [blame] | 234 | void writeToProto(ProtoOutputStream proto, long fieldId) { |
| 235 | long token = proto.start(fieldId); |
| 236 | proto.write(ServiceRecordProto.SHORT_NAME, this.shortName); |
Yi Jin | 6b51414 | 2017-10-30 14:54:12 -0700 | [diff] [blame] | 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 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 343 | void dump(PrintWriter pw, String prefix) { |
Dianne Hackborn | 1d442e0 | 2009-04-20 18:14:05 -0700 | [diff] [blame] | 344 | pw.print(prefix); pw.print("intent={"); |
Dianne Hackborn | 21c241e | 2012-03-08 13:57:23 -0800 | [diff] [blame] | 345 | pw.print(intent.getIntent().toShortString(false, true, false, true)); |
Dianne Hackborn | 1d442e0 | 2009-04-20 18:14:05 -0700 | [diff] [blame] | 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 | } |
Dianne Hackborn | fd12af4 | 2009-08-27 00:44:33 -0700 | [diff] [blame] | 352 | long now = SystemClock.uptimeMillis(); |
Dianne Hackborn | 1ebccf5 | 2010-08-15 13:04:34 -0700 | [diff] [blame] | 353 | long nowReal = SystemClock.elapsedRealtime(); |
Jeff Sharkey | 8a4c972 | 2014-06-16 13:48:42 -0700 | [diff] [blame] | 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); |
Marco Nelissen | a301fe6 | 2011-05-04 08:44:59 -0700 | [diff] [blame] | 360 | } |
Dianne Hackborn | 1d442e0 | 2009-04-20 18:14:05 -0700 | [diff] [blame] | 361 | pw.print(prefix); pw.print("app="); pw.println(app); |
Dianne Hackborn | a0c283e | 2012-02-09 10:47:01 -0800 | [diff] [blame] | 362 | if (isolatedProc != null) { |
| 363 | pw.print(prefix); pw.print("isolatedProc="); pw.println(isolatedProc); |
| 364 | } |
Dianne Hackborn | a590d2b | 2016-06-27 15:07:18 -0700 | [diff] [blame] | 365 | if (whitelistManager) { |
| 366 | pw.print(prefix); pw.print("whitelistManager="); pw.println(whitelistManager); |
| 367 | } |
Dianne Hackborn | 9210bc8 | 2013-09-05 12:31:16 -0700 | [diff] [blame] | 368 | if (delayed) { |
| 369 | pw.print(prefix); pw.print("delayed="); pw.println(delayed); |
| 370 | } |
Dianne Hackborn | d8a43f6 | 2009-08-17 23:33:56 -0700 | [diff] [blame] | 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 | } |
Dianne Hackborn | 9adb9c3 | 2010-08-13 14:09:56 -0700 | [diff] [blame] | 376 | pw.print(prefix); pw.print("createTime="); |
Yi Jin | 6b51414 | 2017-10-30 14:54:12 -0700 | [diff] [blame] | 377 | TimeUtils.formatDuration(createRealTime, nowReal, pw); |
Dianne Hackborn | 9210bc8 | 2013-09-05 12:31:16 -0700 | [diff] [blame] | 378 | pw.print(" startingBgTimeout="); |
| 379 | TimeUtils.formatDuration(startingBgTimeout, now, pw); |
Dianne Hackborn | bf36ee2 | 2013-07-26 18:24:10 -0700 | [diff] [blame] | 380 | pw.println(); |
Dianne Hackborn | 9210bc8 | 2013-09-05 12:31:16 -0700 | [diff] [blame] | 381 | pw.print(prefix); pw.print("lastActivity="); |
| 382 | TimeUtils.formatDuration(lastActivity, now, pw); |
| 383 | pw.print(" restartTime="); |
Dianne Hackborn | 1ebccf5 | 2010-08-15 13:04:34 -0700 | [diff] [blame] | 384 | TimeUtils.formatDuration(restartTime, now, pw); |
Dianne Hackborn | bf36ee2 | 2013-07-26 18:24:10 -0700 | [diff] [blame] | 385 | pw.print(" createdFromFg="); pw.println(createdFromFg); |
Dianne Hackborn | 9210bc8 | 2013-09-05 12:31:16 -0700 | [diff] [blame] | 386 | if (startRequested || delayedStop || lastStartId != 0) { |
Dianne Hackborn | d8a43f6 | 2009-08-17 23:33:56 -0700 | [diff] [blame] | 387 | pw.print(prefix); pw.print("startRequested="); pw.print(startRequested); |
Dianne Hackborn | 9210bc8 | 2013-09-05 12:31:16 -0700 | [diff] [blame] | 388 | pw.print(" delayedStop="); pw.print(delayedStop); |
Dianne Hackborn | f6f9f2d | 2009-08-21 16:26:03 -0700 | [diff] [blame] | 389 | pw.print(" stopIfKilled="); pw.print(stopIfKilled); |
| 390 | pw.print(" callStart="); pw.print(callStart); |
Dianne Hackborn | d8a43f6 | 2009-08-17 23:33:56 -0700 | [diff] [blame] | 391 | pw.print(" lastStartId="); pw.println(lastStartId); |
| 392 | } |
Dianne Hackborn | bf36ee2 | 2013-07-26 18:24:10 -0700 | [diff] [blame] | 393 | if (executeNesting != 0) { |
Dianne Hackborn | d8a43f6 | 2009-08-17 23:33:56 -0700 | [diff] [blame] | 394 | pw.print(prefix); pw.print("executeNesting="); pw.print(executeNesting); |
Dianne Hackborn | bf36ee2 | 2013-07-26 18:24:10 -0700 | [diff] [blame] | 395 | pw.print(" executeFg="); pw.print(executeFg); |
| 396 | pw.print(" executingStart="); |
| 397 | TimeUtils.formatDuration(executingStart, now, pw); |
Dianne Hackborn | 2be0093 | 2013-09-22 16:46:00 -0700 | [diff] [blame] | 398 | pw.println(); |
Dianne Hackborn | bf36ee2 | 2013-07-26 18:24:10 -0700 | [diff] [blame] | 399 | } |
Dianne Hackborn | 455625e | 2015-01-21 09:55:13 -0800 | [diff] [blame] | 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(); |
Craig Mautner | 66c4a82 | 2015-01-16 12:48:16 -0800 | [diff] [blame] | 405 | } |
Dianne Hackborn | bf36ee2 | 2013-07-26 18:24:10 -0700 | [diff] [blame] | 406 | if (crashCount != 0 || restartCount != 0 |
| 407 | || restartDelay != 0 || nextRestartTime != 0) { |
| 408 | pw.print(prefix); pw.print("restartCount="); pw.print(restartCount); |
Dianne Hackborn | 1ebccf5 | 2010-08-15 13:04:34 -0700 | [diff] [blame] | 409 | pw.print(" restartDelay="); |
| 410 | TimeUtils.formatDuration(restartDelay, now, pw); |
| 411 | pw.print(" nextRestartTime="); |
| 412 | TimeUtils.formatDuration(nextRestartTime, now, pw); |
Dianne Hackborn | d8a43f6 | 2009-08-17 23:33:56 -0700 | [diff] [blame] | 413 | pw.print(" crashCount="); pw.println(crashCount); |
| 414 | } |
Dianne Hackborn | f6f9f2d | 2009-08-21 16:26:03 -0700 | [diff] [blame] | 415 | if (deliveredStarts.size() > 0) { |
| 416 | pw.print(prefix); pw.println("Delivered Starts:"); |
Dianne Hackborn | 1ebccf5 | 2010-08-15 13:04:34 -0700 | [diff] [blame] | 417 | dumpStartList(pw, prefix, deliveredStarts, now); |
Dianne Hackborn | f6f9f2d | 2009-08-21 16:26:03 -0700 | [diff] [blame] | 418 | } |
| 419 | if (pendingStarts.size() > 0) { |
| 420 | pw.print(prefix); pw.println("Pending Starts:"); |
| 421 | dumpStartList(pw, prefix, pendingStarts, 0); |
| 422 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 423 | if (bindings.size() > 0) { |
Dianne Hackborn | f6f9f2d | 2009-08-21 16:26:03 -0700 | [diff] [blame] | 424 | pw.print(prefix); pw.println("Bindings:"); |
Dianne Hackborn | 390517b | 2013-05-30 15:03:32 -0700 | [diff] [blame] | 425 | for (int i=0; i<bindings.size(); i++) { |
| 426 | IntentBindRecord b = bindings.valueAt(i); |
Dianne Hackborn | 1d442e0 | 2009-04-20 18:14:05 -0700 | [diff] [blame] | 427 | pw.print(prefix); pw.print("* IntentBindRecord{"); |
| 428 | pw.print(Integer.toHexString(System.identityHashCode(b))); |
Dianne Hackborn | 0c38049 | 2012-08-20 17:23:30 -0700 | [diff] [blame] | 429 | if ((b.collectFlags()&Context.BIND_AUTO_CREATE) != 0) { |
| 430 | pw.append(" CREATE"); |
| 431 | } |
Dianne Hackborn | 1d442e0 | 2009-04-20 18:14:05 -0700 | [diff] [blame] | 432 | pw.println("}:"); |
| 433 | b.dumpInService(pw, prefix + " "); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 434 | } |
| 435 | } |
| 436 | if (connections.size() > 0) { |
Dianne Hackborn | 1d442e0 | 2009-04-20 18:14:05 -0700 | [diff] [blame] | 437 | pw.print(prefix); pw.println("All Connections:"); |
Dianne Hackborn | 390517b | 2013-05-30 15:03:32 -0700 | [diff] [blame] | 438 | for (int conni=0; conni<connections.size(); conni++) { |
| 439 | ArrayList<ConnectionRecord> c = connections.valueAt(conni); |
Dianne Hackborn | 43d9ac8 | 2010-08-25 15:06:25 -0700 | [diff] [blame] | 440 | for (int i=0; i<c.size(); i++) { |
| 441 | pw.print(prefix); pw.print(" "); pw.println(c.get(i)); |
| 442 | } |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 443 | } |
| 444 | } |
| 445 | } |
| 446 | |
Dianne Hackborn | b1c4a2a | 2010-01-19 15:36:42 -0800 | [diff] [blame] | 447 | ServiceRecord(ActivityManagerService ams, |
| 448 | BatteryStatsImpl.Uid.Pkg.Serv servStats, ComponentName name, |
Dianne Hackborn | bf36ee2 | 2013-07-26 18:24:10 -0700 | [diff] [blame] | 449 | Intent.FilterComparison intent, ServiceInfo sInfo, boolean callerIsFg, |
| 450 | Runnable restarter) { |
Dianne Hackborn | b1c4a2a | 2010-01-19 15:36:42 -0800 | [diff] [blame] | 451 | this.ams = ams; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 461 | exported = sInfo.exported; |
| 462 | this.restarter = restarter; |
Yi Jin | 6b51414 | 2017-10-30 14:54:12 -0700 | [diff] [blame] | 463 | createRealTime = SystemClock.elapsedRealtime(); |
Dianne Hackborn | 9adb9c3 | 2010-08-13 14:09:56 -0700 | [diff] [blame] | 464 | lastActivity = SystemClock.uptimeMillis(); |
Dianne Hackborn | f02b60a | 2012-08-16 10:48:27 -0700 | [diff] [blame] | 465 | userId = UserHandle.getUserId(appInfo.uid); |
Dianne Hackborn | bf36ee2 | 2013-07-26 18:24:10 -0700 | [diff] [blame] | 466 | createdFromFg = callerIsFg; |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 467 | } |
| 468 | |
Joe Onorato | 4eb64fd | 2016-03-21 15:30:09 -0700 | [diff] [blame] | 469 | public ServiceState getTracker() { |
Dianne Hackborn | bd754f4 | 2013-07-23 15:52:36 -0700 | [diff] [blame] | 470 | if (tracker != null) { |
| 471 | return tracker; |
| 472 | } |
| 473 | if ((serviceInfo.applicationInfo.flags&ApplicationInfo.FLAG_PERSISTENT) == 0) { |
Dianne Hackborn | d293224 | 2013-08-05 18:18:42 -0700 | [diff] [blame] | 474 | tracker = ams.mProcessStats.getServiceStateLocked(serviceInfo.packageName, |
Dianne Hackborn | 8472e61 | 2014-01-23 17:57:20 -0800 | [diff] [blame] | 475 | serviceInfo.applicationInfo.uid, serviceInfo.applicationInfo.versionCode, |
| 476 | serviceInfo.processName, serviceInfo.name); |
Dianne Hackborn | 164371f | 2013-10-01 19:10:13 -0700 | [diff] [blame] | 477 | tracker.applyNewOwner(this); |
Dianne Hackborn | bd754f4 | 2013-07-23 15:52:36 -0700 | [diff] [blame] | 478 | } |
| 479 | return tracker; |
| 480 | } |
| 481 | |
Dianne Hackborn | 164371f | 2013-10-01 19:10:13 -0700 | [diff] [blame] | 482 | public void forceClearTracker() { |
| 483 | if (tracker != null) { |
Dianne Hackborn | 878deb3 | 2013-10-14 16:55:09 -0700 | [diff] [blame] | 484 | tracker.clearCurrentOwner(this, true); |
Dianne Hackborn | 164371f | 2013-10-01 19:10:13 -0700 | [diff] [blame] | 485 | tracker = null; |
| 486 | } |
| 487 | } |
| 488 | |
Dianne Hackborn | daa0d5c | 2013-11-06 16:30:29 -0800 | [diff] [blame] | 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, |
Dianne Hackborn | 8472e61 | 2014-01-23 17:57:20 -0800 | [diff] [blame] | 493 | serviceInfo.applicationInfo.uid, serviceInfo.applicationInfo.versionCode, |
| 494 | serviceInfo.processName, serviceInfo.name); |
Dianne Hackborn | daa0d5c | 2013-11-06 16:30:29 -0800 | [diff] [blame] | 495 | } |
| 496 | if (restartTracker == null) { |
| 497 | return; |
| 498 | } |
| 499 | } |
| 500 | restartTracker.setRestarting(true, memFactor, now); |
| 501 | } |
| 502 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 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 | |
Dianne Hackborn | 91268cf | 2013-06-13 19:06:50 -0700 | [diff] [blame] | 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 | |
Dianne Hackborn | a590d2b | 2016-06-27 15:07:18 -0700 | [diff] [blame] | 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 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 547 | public void resetRestartCounter() { |
| 548 | restartCount = 0; |
| 549 | restartDelay = 0; |
| 550 | restartTime = 0; |
| 551 | } |
Geoffrey Pitsch | af759c5 | 2017-02-15 09:35:38 -0500 | [diff] [blame] | 552 | |
Dianne Hackborn | f6f9f2d | 2009-08-21 16:26:03 -0700 | [diff] [blame] | 553 | public StartItem findDeliveredStart(int id, 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) { |
| 558 | if (remove) deliveredStarts.remove(i); |
| 559 | return si; |
| 560 | } |
| 561 | } |
Geoffrey Pitsch | af759c5 | 2017-02-15 09:35:38 -0500 | [diff] [blame] | 562 | |
Dianne Hackborn | f6f9f2d | 2009-08-21 16:26:03 -0700 | [diff] [blame] | 563 | return null; |
| 564 | } |
Geoffrey Pitsch | af759c5 | 2017-02-15 09:35:38 -0500 | [diff] [blame] | 565 | |
Dianne Hackborn | 0c5001d | 2011-04-12 18:16:08 -0700 | [diff] [blame] | 566 | public int getLastStartId() { |
| 567 | return lastStartId; |
| 568 | } |
| 569 | |
| 570 | public int makeNextStartId() { |
| 571 | lastStartId++; |
| 572 | if (lastStartId < 1) { |
| 573 | lastStartId = 1; |
| 574 | } |
| 575 | return lastStartId; |
| 576 | } |
| 577 | |
Dianne Hackborn | d8a43f6 | 2009-08-17 23:33:56 -0700 | [diff] [blame] | 578 | public void postNotification() { |
Daniel Sandler | d0a2f86 | 2010-08-03 15:29:31 -0400 | [diff] [blame] | 579 | final int appUid = appInfo.uid; |
| 580 | final int appPid = app.pid; |
Dianne Hackborn | d8a43f6 | 2009-08-17 23:33:56 -0700 | [diff] [blame] | 581 | if (foregroundId != 0 && foregroundNoti != null) { |
Dianne Hackborn | b1c4a2a | 2010-01-19 15:36:42 -0800 | [diff] [blame] | 582 | // Do asynchronous communication with notification manager to |
| 583 | // avoid deadlocks. |
| 584 | final String localPackageName = packageName; |
| 585 | final int localForegroundId = foregroundId; |
Dan Sandler | d63f932 | 2015-05-06 15:18:49 -0400 | [diff] [blame] | 586 | final Notification _foregroundNoti = foregroundNoti; |
Dianne Hackborn | b1c4a2a | 2010-01-19 15:36:42 -0800 | [diff] [blame] | 587 | ams.mHandler.post(new Runnable() { |
| 588 | public void run() { |
Adam Lesinski | 182f73f | 2013-12-05 16:48:06 -0800 | [diff] [blame] | 589 | NotificationManagerInternal nm = LocalServices.getService( |
| 590 | NotificationManagerInternal.class); |
Daniel Sandler | d0a2f86 | 2010-08-03 15:29:31 -0400 | [diff] [blame] | 591 | if (nm == null) { |
Dianne Hackborn | b1c4a2a | 2010-01-19 15:36:42 -0800 | [diff] [blame] | 592 | return; |
| 593 | } |
Dan Sandler | d63f932 | 2015-05-06 15:18:49 -0400 | [diff] [blame] | 594 | Notification localForegroundNoti = _foregroundNoti; |
Dianne Hackborn | b1c4a2a | 2010-01-19 15:36:42 -0800 | [diff] [blame] | 595 | try { |
Dan Sandler | d63f932 | 2015-05-06 15:18:49 -0400 | [diff] [blame] | 596 | if (localForegroundNoti.getSmallIcon() == null) { |
Wang Le | e2c1f9b | 2016-05-04 19:24:35 +0800 | [diff] [blame] | 597 | // It is not correct for the caller to not supply a notification |
Dianne Hackborn | 2ced96c | 2013-03-21 14:23:46 -0700 | [diff] [blame] | 598 | // icon, but this used to be able to slip through, so for |
Dan Sandler | d63f932 | 2015-05-06 15:18:49 -0400 | [diff] [blame] | 599 | // those dirty apps we will create a notification clearly |
| 600 | // blaming the app. |
Dan Sandler | 4e78706 | 2015-06-17 15:09:48 -0400 | [diff] [blame] | 601 | Slog.v(TAG, "Attempted to start a foreground service (" |
| 602 | + name |
| 603 | + ") with a broken notification (no icon: " |
| 604 | + localForegroundNoti |
| 605 | + ")"); |
Daniel Sandler | 91fe845 | 2013-04-08 12:23:27 -0400 | [diff] [blame] | 606 | |
Daniel Sandler | 91fe845 | 2013-04-08 12:23:27 -0400 | [diff] [blame] | 607 | CharSequence appName = appInfo.loadLabel( |
| 608 | ams.mContext.getPackageManager()); |
| 609 | if (appName == null) { |
| 610 | appName = appInfo.packageName; |
| 611 | } |
| 612 | Context ctx = null; |
| 613 | try { |
Wang Le | e2c1f9b | 2016-05-04 19:24:35 +0800 | [diff] [blame] | 614 | ctx = ams.mContext.createPackageContextAsUser( |
| 615 | appInfo.packageName, 0, new UserHandle(userId)); |
Dan Sandler | d63f932 | 2015-05-06 15:18:49 -0400 | [diff] [blame] | 616 | |
Geoffrey Pitsch | af759c5 | 2017-02-15 09:35:38 -0500 | [diff] [blame] | 617 | Notification.Builder notiBuilder = new Notification.Builder(ctx, |
Julia Reynolds | bad4297 | 2017-04-25 13:52:49 -0400 | [diff] [blame] | 618 | localForegroundNoti.getChannelId()); |
Dan Sandler | d63f932 | 2015-05-06 15:18:49 -0400 | [diff] [blame] | 619 | |
| 620 | // it's ugly, but it clearly identifies the app |
| 621 | notiBuilder.setSmallIcon(appInfo.icon); |
| 622 | |
Dan Sandler | 4e78706 | 2015-06-17 15:09:48 -0400 | [diff] [blame] | 623 | // mark as foreground |
| 624 | notiBuilder.setFlag(Notification.FLAG_FOREGROUND_SERVICE, true); |
| 625 | |
Daniel Sandler | 91fe845 | 2013-04-08 12:23:27 -0400 | [diff] [blame] | 626 | Intent runningIntent = new Intent( |
| 627 | Settings.ACTION_APPLICATION_DETAILS_SETTINGS); |
| 628 | runningIntent.setData(Uri.fromParts("package", |
| 629 | appInfo.packageName, null)); |
luozhanwei | 279544c | 2017-04-05 13:30:53 +0800 | [diff] [blame] | 630 | PendingIntent pi = PendingIntent.getActivityAsUser(ams.mContext, 0, |
| 631 | runningIntent, PendingIntent.FLAG_UPDATE_CURRENT, null, |
| 632 | UserHandle.of(userId)); |
Dan Sandler | d63f932 | 2015-05-06 15:18:49 -0400 | [diff] [blame] | 633 | notiBuilder.setColor(ams.mContext.getColor( |
Selim Cinek | 255dd04 | 2014-08-19 22:29:02 +0200 | [diff] [blame] | 634 | com.android.internal |
Dan Sandler | d63f932 | 2015-05-06 15:18:49 -0400 | [diff] [blame] | 635 | .R.color.system_notification_accent_color)); |
| 636 | notiBuilder.setContentTitle( |
Daniel Sandler | 91fe845 | 2013-04-08 12:23:27 -0400 | [diff] [blame] | 637 | ams.mContext.getString( |
| 638 | com.android.internal.R.string |
| 639 | .app_running_notification_title, |
Dan Sandler | d63f932 | 2015-05-06 15:18:49 -0400 | [diff] [blame] | 640 | appName)); |
| 641 | notiBuilder.setContentText( |
Daniel Sandler | 91fe845 | 2013-04-08 12:23:27 -0400 | [diff] [blame] | 642 | ams.mContext.getString( |
| 643 | com.android.internal.R.string |
| 644 | .app_running_notification_text, |
Dan Sandler | d63f932 | 2015-05-06 15:18:49 -0400 | [diff] [blame] | 645 | appName)); |
| 646 | notiBuilder.setContentIntent(pi); |
| 647 | |
| 648 | localForegroundNoti = notiBuilder.build(); |
Daniel Sandler | 91fe845 | 2013-04-08 12:23:27 -0400 | [diff] [blame] | 649 | } catch (PackageManager.NameNotFoundException e) { |
Dianne Hackborn | 2ced96c | 2013-03-21 14:23:46 -0700 | [diff] [blame] | 650 | } |
| 651 | } |
Julia Reynolds | 5a4399a | 2017-10-11 08:44:46 -0400 | [diff] [blame] | 652 | if (nm.getNotificationChannel(localPackageName, appUid, |
Julia Reynolds | f3de8aa | 2017-09-29 15:52:37 -0400 | [diff] [blame] | 653 | localForegroundNoti.getChannelId()) == null) { |
Julia Reynolds | 5a4399a | 2017-10-11 08:44:46 -0400 | [diff] [blame] | 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) { |
Dianne Hackborn | 282add7 | 2013-03-15 18:48:04 -0700 | [diff] [blame] | 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. |
Dan Sandler | d63f932 | 2015-05-06 15:18:49 -0400 | [diff] [blame] | 673 | throw new RuntimeException("invalid service notification: " |
| 674 | + foregroundNoti); |
Dianne Hackborn | 282add7 | 2013-03-15 18:48:04 -0700 | [diff] [blame] | 675 | } |
Adam Lesinski | 182f73f | 2013-12-05 16:48:06 -0800 | [diff] [blame] | 676 | nm.enqueueNotification(localPackageName, localPackageName, |
Dianne Hackborn | f265ea9 | 2013-01-31 15:00:51 -0800 | [diff] [blame] | 677 | appUid, appPid, null, localForegroundId, localForegroundNoti, |
Julia Reynolds | fea6f7b | 2017-04-19 13:50:12 -0400 | [diff] [blame] | 678 | userId); |
Dan Sandler | 4e78706 | 2015-06-17 15:09:48 -0400 | [diff] [blame] | 679 | |
| 680 | foregroundNoti = localForegroundNoti; // save it for amending next time |
Joe Onorato | 34fcf97 | 2010-02-18 07:45:17 -0500 | [diff] [blame] | 681 | } catch (RuntimeException e) { |
Wale Ogunwale | e23149f | 2015-03-06 15:39:44 -0800 | [diff] [blame] | 682 | Slog.w(TAG, "Error showing notification for service", e); |
Dianne Hackborn | 9e0f5d9 | 2010-02-22 15:05:42 -0800 | [diff] [blame] | 683 | // If it gave us a garbage notification, it doesn't |
| 684 | // get to be foreground. |
| 685 | ams.setServiceForeground(name, ServiceRecord.this, |
Dianne Hackborn | 67324c9 | 2016-04-18 13:55:25 -0700 | [diff] [blame] | 686 | 0, null, 0); |
Christopher Tate | 8aa8fe1 | 2017-01-20 17:50:32 -0800 | [diff] [blame] | 687 | ams.crashApplication(appUid, appPid, localPackageName, -1, |
Joe Onorato | eaa0718 | 2010-09-23 16:49:20 -0700 | [diff] [blame] | 688 | "Bad notification for startForeground: " + e); |
Dianne Hackborn | b1c4a2a | 2010-01-19 15:36:42 -0800 | [diff] [blame] | 689 | } |
Dianne Hackborn | d8a43f6 | 2009-08-17 23:33:56 -0700 | [diff] [blame] | 690 | } |
Dianne Hackborn | b1c4a2a | 2010-01-19 15:36:42 -0800 | [diff] [blame] | 691 | }); |
Dianne Hackborn | d8a43f6 | 2009-08-17 23:33:56 -0700 | [diff] [blame] | 692 | } |
| 693 | } |
Geoffrey Pitsch | af759c5 | 2017-02-15 09:35:38 -0500 | [diff] [blame] | 694 | |
Dianne Hackborn | d8a43f6 | 2009-08-17 23:33:56 -0700 | [diff] [blame] | 695 | public void cancelNotification() { |
Dianne Hackborn | 0ba4c71 | 2016-08-01 17:49:41 -0700 | [diff] [blame] | 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; |
Dianne Hackborn | d8a43f6 | 2009-08-17 23:33:56 -0700 | [diff] [blame] | 705 | } |
Dianne Hackborn | 0ba4c71 | 2016-08-01 17:49:41 -0700 | [diff] [blame] | 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 | }); |
Dianne Hackborn | d8a43f6 | 2009-08-17 23:33:56 -0700 | [diff] [blame] | 715 | } |
Christoph Studer | 365e4c3 | 2014-09-18 20:35:36 +0200 | [diff] [blame] | 716 | |
| 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 | } |
Geoffrey Pitsch | af759c5 | 2017-02-15 09:35:38 -0500 | [diff] [blame] | 741 | |
Dianne Hackborn | 39792d2 | 2010-08-19 18:01:52 -0700 | [diff] [blame] | 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 | |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 749 | public String toString() { |
Dianne Hackborn | f210d6b | 2009-04-13 18:42:49 -0700 | [diff] [blame] | 750 | if (stringName != null) { |
| 751 | return stringName; |
| 752 | } |
| 753 | StringBuilder sb = new StringBuilder(128); |
Dianne Hackborn | 1d442e0 | 2009-04-20 18:14:05 -0700 | [diff] [blame] | 754 | sb.append("ServiceRecord{") |
| 755 | .append(Integer.toHexString(System.identityHashCode(this))) |
Dianne Hackborn | b12e135 | 2012-09-26 11:39:20 -0700 | [diff] [blame] | 756 | .append(" u").append(userId) |
Dianne Hackborn | 1d442e0 | 2009-04-20 18:14:05 -0700 | [diff] [blame] | 757 | .append(' ').append(shortName).append('}'); |
Dianne Hackborn | f210d6b | 2009-04-13 18:42:49 -0700 | [diff] [blame] | 758 | return stringName = sb.toString(); |
The Android Open Source Project | 9066cfe | 2009-03-03 19:31:44 -0800 | [diff] [blame] | 759 | } |
| 760 | } |