Merge "Dump App exit reason if the remote service died." into tm-qpr-dev
This commit is contained in:
@@ -1196,7 +1196,8 @@ public final class ApplicationExitInfo implements Parcelable {
|
|||||||
return sb.toString();
|
return sb.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String reasonCodeToString(@Reason int reason) {
|
/** @hide */
|
||||||
|
public static String reasonCodeToString(@Reason int reason) {
|
||||||
switch (reason) {
|
switch (reason) {
|
||||||
case REASON_EXIT_SELF:
|
case REASON_EXIT_SELF:
|
||||||
return "EXIT_SELF";
|
return "EXIT_SELF";
|
||||||
|
|||||||
@@ -20,10 +20,14 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa
|
|||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.app.ActivityManager;
|
||||||
|
import android.app.ApplicationExitInfo;
|
||||||
|
import android.app.IActivityManager;
|
||||||
import android.content.ComponentName;
|
import android.content.ComponentName;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.ServiceConnection;
|
import android.content.ServiceConnection;
|
||||||
|
import android.content.pm.ParceledListSlice;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.IBinder.DeathRecipient;
|
import android.os.IBinder.DeathRecipient;
|
||||||
@@ -39,6 +43,7 @@ import com.android.internal.annotations.GuardedBy;
|
|||||||
import java.io.PrintWriter;
|
import java.io.PrintWriter;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base class representing a remote service.
|
* Base class representing a remote service.
|
||||||
@@ -66,6 +71,7 @@ import java.util.ArrayList;
|
|||||||
@Deprecated
|
@Deprecated
|
||||||
public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I>,
|
public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I>,
|
||||||
I extends IInterface> implements DeathRecipient {
|
I extends IInterface> implements DeathRecipient {
|
||||||
|
private static final int SERVICE_NOT_EXIST = -1;
|
||||||
private static final int MSG_BIND = 1;
|
private static final int MSG_BIND = 1;
|
||||||
private static final int MSG_UNBIND = 2;
|
private static final int MSG_UNBIND = 2;
|
||||||
|
|
||||||
@@ -96,6 +102,8 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
|
|||||||
|
|
||||||
// Used just for debugging purposes (on dump)
|
// Used just for debugging purposes (on dump)
|
||||||
private long mNextUnbind;
|
private long mNextUnbind;
|
||||||
|
private int mServiceExitReason;
|
||||||
|
private int mServiceExitSubReason;
|
||||||
|
|
||||||
/** Requests that have been scheduled, but that are not finished yet */
|
/** Requests that have been scheduled, but that are not finished yet */
|
||||||
private final ArrayList<BasePendingRequest<S, I>> mUnfinishedRequests = new ArrayList<>();
|
private final ArrayList<BasePendingRequest<S, I>> mUnfinishedRequests = new ArrayList<>();
|
||||||
@@ -126,6 +134,8 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
|
|||||||
mUserId = userId;
|
mUserId = userId;
|
||||||
mHandler = new Handler(handler.getLooper());
|
mHandler = new Handler(handler.getLooper());
|
||||||
mBindingFlags = bindingFlags;
|
mBindingFlags = bindingFlags;
|
||||||
|
mServiceExitReason = SERVICE_NOT_EXIST;
|
||||||
|
mServiceExitSubReason = SERVICE_NOT_EXIST;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -229,6 +239,7 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
|
|||||||
if (mService != null) {
|
if (mService != null) {
|
||||||
mService.asBinder().unlinkToDeath(this, 0);
|
mService.asBinder().unlinkToDeath(this, 0);
|
||||||
}
|
}
|
||||||
|
updateServicelicationExitInfo(mComponentName, mUserId);
|
||||||
mConnecting = true;
|
mConnecting = true;
|
||||||
mService = null;
|
mService = null;
|
||||||
mServiceDied = true;
|
mServiceDied = true;
|
||||||
@@ -239,6 +250,37 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
|
|||||||
handleBindFailure();
|
handleBindFailure();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateServicelicationExitInfo(ComponentName componentName, int userId) {
|
||||||
|
IActivityManager am = ActivityManager.getService();
|
||||||
|
String packageName = componentName.getPackageName();
|
||||||
|
ParceledListSlice<ApplicationExitInfo> plistSlice = null;
|
||||||
|
try {
|
||||||
|
plistSlice = am.getHistoricalProcessExitReasons(packageName, 0, 1, userId);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
// do nothing. The local binder so it can not throw it.
|
||||||
|
}
|
||||||
|
if (plistSlice == null) {
|
||||||
|
mServiceExitReason = ApplicationExitInfo.REASON_UNKNOWN;
|
||||||
|
mServiceExitSubReason = ApplicationExitInfo.SUBREASON_UNKNOWN;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
List<ApplicationExitInfo> list = plistSlice.getList();
|
||||||
|
if (list.isEmpty()) {
|
||||||
|
mServiceExitReason = ApplicationExitInfo.REASON_UNKNOWN;
|
||||||
|
mServiceExitSubReason = ApplicationExitInfo.SUBREASON_UNKNOWN;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ApplicationExitInfo info = list.get(0);
|
||||||
|
mServiceExitReason = info.getReason();
|
||||||
|
mServiceExitSubReason = info.getSubReason();
|
||||||
|
if (mVerbose) {
|
||||||
|
Slog.v(mTag, "updateServicelicationExitInfo: exitReason="
|
||||||
|
+ ApplicationExitInfo.reasonCodeToString(mServiceExitReason)
|
||||||
|
+ " exitSubReason= " + ApplicationExitInfo.subreasonToString(
|
||||||
|
mServiceExitSubReason));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Note: we are dumping without a lock held so this is a bit racy but
|
// Note: we are dumping without a lock held so this is a bit racy but
|
||||||
// adding a lock to a class that offloads to a handler thread would
|
// adding a lock to a class that offloads to a handler thread would
|
||||||
// mean adding a lock adding overhead to normal runtime operation.
|
// mean adding a lock adding overhead to normal runtime operation.
|
||||||
@@ -272,6 +314,16 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
pw.println();
|
pw.println();
|
||||||
|
if (mServiceExitReason != SERVICE_NOT_EXIST) {
|
||||||
|
pw.append(prefix).append(tab).append("serviceExistReason=")
|
||||||
|
.append(ApplicationExitInfo.reasonCodeToString(mServiceExitReason));
|
||||||
|
pw.println();
|
||||||
|
}
|
||||||
|
if (mServiceExitSubReason != SERVICE_NOT_EXIST) {
|
||||||
|
pw.append(prefix).append(tab).append("serviceExistSubReason=")
|
||||||
|
.append(ApplicationExitInfo.subreasonToString(mServiceExitSubReason));
|
||||||
|
pw.println();
|
||||||
|
}
|
||||||
pw.append(prefix).append("mBindingFlags=").println(mBindingFlags);
|
pw.append(prefix).append("mBindingFlags=").println(mBindingFlags);
|
||||||
pw.append(prefix).append("idleTimeout=")
|
pw.append(prefix).append("idleTimeout=")
|
||||||
.append(Long.toString(idleTimeout / 1000)).append("s\n");
|
.append(Long.toString(idleTimeout / 1000)).append("s\n");
|
||||||
@@ -498,6 +550,8 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mService = getServiceInterface(service);
|
mService = getServiceInterface(service);
|
||||||
|
mServiceExitReason = SERVICE_NOT_EXIST;
|
||||||
|
mServiceExitSubReason = SERVICE_NOT_EXIST;
|
||||||
handleOnConnectedStateChangedInternal(true);
|
handleOnConnectedStateChangedInternal(true);
|
||||||
mServiceDied = false;
|
mServiceDied = false;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user