/* * Copyright (C) 2006 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.am; import com.android.internal.app.ProcessStats; import com.android.internal.os.BatteryStatsImpl; import com.android.server.LocalServices; import com.android.server.notification.NotificationManagerInternal; import android.app.INotificationManager; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.content.pm.ServiceInfo; import android.net.Uri; import android.os.Binder; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemClock; import android.os.UserHandle; import android.provider.Settings; import android.util.ArrayMap; import android.util.Slog; import android.util.TimeUtils; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Objects; /** * A running application service. */ final class ServiceRecord extends Binder { // Maximum number of delivery attempts before giving up. static final int MAX_DELIVERY_COUNT = 3; // Maximum number of times it can fail during execution before giving up. static final int MAX_DONE_EXECUTING_COUNT = 6; final ActivityManagerService ams; final BatteryStatsImpl.Uid.Pkg.Serv stats; final ComponentName name; // service component. final String shortName; // name.flattenToShortString(). final Intent.FilterComparison intent; // original intent used to find service. final ServiceInfo serviceInfo; // all information about the service. final ApplicationInfo appInfo; // information about service's app. final int userId; // user that this service is running as final String packageName; // the package implementing intent's component final String processName; // process where this component wants to run final String permission;// permission needed to access service final boolean exported; // from ServiceInfo.exported final Runnable restarter; // used to schedule retries of starting the service final long createTime; // when this service was created final ArrayMap bindings = new ArrayMap(); // All active bindings to the service. final ArrayMap> connections = new ArrayMap>(); // IBinder -> ConnectionRecord of all bound clients ProcessRecord app; // where this service is running or null. ProcessRecord isolatedProc; // keep track of isolated process, if requested ProcessStats.ServiceState tracker; // tracking service execution, may be null ProcessStats.ServiceState restartTracker; // tracking service restart boolean delayed; // are we waiting to start this service in the background? boolean isForeground; // is service currently in foreground mode? int foregroundId; // Notification ID of last foreground req. Notification foregroundNoti; // Notification record of foreground state. long lastActivity; // last time there was some activity on the service. long startingBgTimeout; // time at which we scheduled this for a delayed start. boolean startRequested; // someone explicitly called start? boolean delayedStop; // service has been stopped but is in a delayed start? boolean stopIfKilled; // last onStart() said to stop if service killed? boolean callStart; // last onStart() has asked to alway be called on restart. int executeNesting; // number of outstanding operations keeping foreground. boolean executeFg; // should we be executing in the foreground? long executingStart; // start time of last execute request. boolean createdFromFg; // was this service last created due to a foreground process call? int crashCount; // number of times proc has crashed with service running int totalRestartCount; // number of times we have had to restart. int restartCount; // number of restarts performed in a row. long restartDelay; // delay until next restart attempt. long restartTime; // time of last restart. long nextRestartTime; // time when restartDelay will expire. String stringName; // caching of toString private int lastStartId; // identifier of most recent start request. static class StartItem { final ServiceRecord sr; final boolean taskRemoved; final int id; final Intent intent; final ActivityManagerService.NeededUriGrants neededGrants; long deliveredTime; int deliveryCount; int doneExecutingCount; UriPermissionOwner uriPermissions; String stringName; // caching of toString StartItem(ServiceRecord _sr, boolean _taskRemoved, int _id, Intent _intent, ActivityManagerService.NeededUriGrants _neededGrants) { sr = _sr; taskRemoved = _taskRemoved; id = _id; intent = _intent; neededGrants = _neededGrants; } UriPermissionOwner getUriPermissionsLocked() { if (uriPermissions == null) { uriPermissions = new UriPermissionOwner(sr.ams, this); } return uriPermissions; } void removeUriPermissionsLocked() { if (uriPermissions != null) { uriPermissions.removeUriPermissionsLocked(); uriPermissions = null; } } public String toString() { if (stringName != null) { return stringName; } StringBuilder sb = new StringBuilder(128); sb.append("ServiceRecord{") .append(Integer.toHexString(System.identityHashCode(sr))) .append(' ').append(sr.shortName) .append(" StartItem ") .append(Integer.toHexString(System.identityHashCode(this))) .append(" id=").append(id).append('}'); return stringName = sb.toString(); } } final ArrayList deliveredStarts = new ArrayList(); // start() arguments which been delivered. final ArrayList pendingStarts = new ArrayList(); // start() arguments that haven't yet been delivered. void dumpStartList(PrintWriter pw, String prefix, List list, long now) { final int N = list.size(); for (int i=0; i 0) { pw.print(prefix); pw.println("Pending Starts:"); dumpStartList(pw, prefix, pendingStarts, 0); } if (bindings.size() > 0) { pw.print(prefix); pw.println("Bindings:"); for (int i=0; i 0) { pw.print(prefix); pw.println("All Connections:"); for (int conni=0; conni c = connections.valueAt(conni); for (int i=0; i=0; conni--) { ArrayList cr = connections.valueAt(conni); for (int i=0; i=0; i--) { deliveredStarts.get(i).removeUriPermissionsLocked(); } deliveredStarts.clear(); } public String toString() { if (stringName != null) { return stringName; } StringBuilder sb = new StringBuilder(128); sb.append("ServiceRecord{") .append(Integer.toHexString(System.identityHashCode(this))) .append(" u").append(userId) .append(' ').append(shortName).append('}'); return stringName = sb.toString(); } }