Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 055796e8 authored by Joanne Chung's avatar Joanne Chung Committed by Android (Google) Code Review
Browse files

Merge "Dump App exit reason if the remote service died." into tm-qpr-dev

parents 389d8389 908ee5ed
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -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";
+54 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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.
@@ -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;

@@ -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<>();
@@ -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;
    }

    /**
@@ -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;
@@ -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.
@@ -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");
@@ -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;
        }