Loading core/java/android/app/ApplicationExitInfo.java +2 −1 Original line number Diff line number Diff line Loading @@ -1196,7 +1196,8 @@ public final class ApplicationExitInfo implements Parcelable { return sb.toString(); } private static String reasonCodeToString(@Reason int reason) { /** @hide */ public static String reasonCodeToString(@Reason int reason) { switch (reason) { case REASON_EXIT_SELF: return "EXIT_SELF"; Loading core/java/com/android/internal/infra/AbstractRemoteService.java +54 −0 Original line number Diff line number Diff line Loading @@ -20,10 +20,14 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ApplicationExitInfo; import android.app.IActivityManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.ParceledListSlice; import android.os.Handler; import android.os.IBinder; import android.os.IBinder.DeathRecipient; Loading @@ -39,6 +43,7 @@ import com.android.internal.annotations.GuardedBy; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; /** * Base class representing a remote service. Loading Loading @@ -66,6 +71,7 @@ import java.util.ArrayList; @Deprecated public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I>, 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_UNBIND = 2; Loading Loading @@ -96,6 +102,8 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I // Used just for debugging purposes (on dump) private long mNextUnbind; private int mServiceExitReason; private int mServiceExitSubReason; /** Requests that have been scheduled, but that are not finished yet */ private final ArrayList<BasePendingRequest<S, I>> mUnfinishedRequests = new ArrayList<>(); Loading Loading @@ -126,6 +134,8 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I mUserId = userId; mHandler = new Handler(handler.getLooper()); mBindingFlags = bindingFlags; mServiceExitReason = SERVICE_NOT_EXIST; mServiceExitSubReason = SERVICE_NOT_EXIST; } /** Loading Loading @@ -229,6 +239,7 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I if (mService != null) { mService.asBinder().unlinkToDeath(this, 0); } updateServicelicationExitInfo(mComponentName, mUserId); mConnecting = true; mService = null; mServiceDied = true; Loading @@ -239,6 +250,37 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I 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 // adding a lock to a class that offloads to a handler thread would // mean adding a lock adding overhead to normal runtime operation. Loading Loading @@ -272,6 +314,16 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I } } 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("idleTimeout=") .append(Long.toString(idleTimeout / 1000)).append("s\n"); Loading Loading @@ -498,6 +550,8 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I return; } mService = getServiceInterface(service); mServiceExitReason = SERVICE_NOT_EXIST; mServiceExitSubReason = SERVICE_NOT_EXIST; handleOnConnectedStateChangedInternal(true); mServiceDied = false; } Loading Loading
core/java/android/app/ApplicationExitInfo.java +2 −1 Original line number Diff line number Diff line Loading @@ -1196,7 +1196,8 @@ public final class ApplicationExitInfo implements Parcelable { return sb.toString(); } private static String reasonCodeToString(@Reason int reason) { /** @hide */ public static String reasonCodeToString(@Reason int reason) { switch (reason) { case REASON_EXIT_SELF: return "EXIT_SELF"; Loading
core/java/com/android/internal/infra/AbstractRemoteService.java +54 −0 Original line number Diff line number Diff line Loading @@ -20,10 +20,14 @@ import static com.android.internal.util.function.pooled.PooledLambda.obtainMessa import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ApplicationExitInfo; import android.app.IActivityManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.pm.ParceledListSlice; import android.os.Handler; import android.os.IBinder; import android.os.IBinder.DeathRecipient; Loading @@ -39,6 +43,7 @@ import com.android.internal.annotations.GuardedBy; import java.io.PrintWriter; import java.lang.ref.WeakReference; import java.util.ArrayList; import java.util.List; /** * Base class representing a remote service. Loading Loading @@ -66,6 +71,7 @@ import java.util.ArrayList; @Deprecated public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I>, 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_UNBIND = 2; Loading Loading @@ -96,6 +102,8 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I // Used just for debugging purposes (on dump) private long mNextUnbind; private int mServiceExitReason; private int mServiceExitSubReason; /** Requests that have been scheduled, but that are not finished yet */ private final ArrayList<BasePendingRequest<S, I>> mUnfinishedRequests = new ArrayList<>(); Loading Loading @@ -126,6 +134,8 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I mUserId = userId; mHandler = new Handler(handler.getLooper()); mBindingFlags = bindingFlags; mServiceExitReason = SERVICE_NOT_EXIST; mServiceExitSubReason = SERVICE_NOT_EXIST; } /** Loading Loading @@ -229,6 +239,7 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I if (mService != null) { mService.asBinder().unlinkToDeath(this, 0); } updateServicelicationExitInfo(mComponentName, mUserId); mConnecting = true; mService = null; mServiceDied = true; Loading @@ -239,6 +250,37 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I 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 // adding a lock to a class that offloads to a handler thread would // mean adding a lock adding overhead to normal runtime operation. Loading Loading @@ -272,6 +314,16 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I } } 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("idleTimeout=") .append(Long.toString(idleTimeout / 1000)).append("s\n"); Loading Loading @@ -498,6 +550,8 @@ public abstract class AbstractRemoteService<S extends AbstractRemoteService<S, I return; } mService = getServiceInterface(service); mServiceExitReason = SERVICE_NOT_EXIST; mServiceExitSubReason = SERVICE_NOT_EXIST; handleOnConnectedStateChangedInternal(true); mServiceDied = false; } Loading