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

Commit b9416234 authored by Patrick Williams's avatar Patrick Williams Committed by Android (Google) Code Review
Browse files

Merge "Add stalled transaction message to input ANRs" into main

parents 35f013c6 34b0a0c0
Loading
Loading
Loading
Loading
+9 −0
Original line number Original line Diff line number Diff line
@@ -47,6 +47,7 @@ import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.Rect;
import android.graphics.Region;
import android.graphics.Region;
import android.gui.DropInputMode;
import android.gui.DropInputMode;
import android.gui.StalledTransactionInfo;
import android.hardware.DataSpace;
import android.hardware.DataSpace;
import android.hardware.HardwareBuffer;
import android.hardware.HardwareBuffer;
import android.hardware.OverlayProperties;
import android.hardware.OverlayProperties;
@@ -292,6 +293,7 @@ public final class SurfaceControl implements Parcelable {
            long nativeObject, long nativeTpc, TrustedPresentationThresholds thresholds);
            long nativeObject, long nativeTpc, TrustedPresentationThresholds thresholds);
    private static native void nativeClearTrustedPresentationCallback(long transactionObj,
    private static native void nativeClearTrustedPresentationCallback(long transactionObj,
            long nativeObject);
            long nativeObject);
    private static native StalledTransactionInfo nativeGetStalledTransactionInfo(int pid);


    /**
    /**
     * Transforms that can be applied to buffers as they are displayed to a window.
     * Transforms that can be applied to buffers as they are displayed to a window.
@@ -4363,4 +4365,11 @@ public final class SurfaceControl implements Parcelable {
        callback.accept(fence);
        callback.accept(fence);
    }
    }


    /**
     * @hide
     */
    public static StalledTransactionInfo getStalledTransactionInfo(int pid) {
        return nativeGetStalledTransactionInfo(pid);
    }

}
}
+45 −0
Original line number Original line Diff line number Diff line
@@ -257,6 +257,14 @@ static struct {
    jmethodID onTrustedPresentationChanged;
    jmethodID onTrustedPresentationChanged;
} gTrustedPresentationCallbackClassInfo;
} gTrustedPresentationCallbackClassInfo;


static struct {
    jclass clazz;
    jmethodID ctor;
    jfieldID layerName;
    jfieldID bufferId;
    jfieldID frameNumber;
} gStalledTransactionInfoClassInfo;

constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) {
constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) {
    switch (colorMode) {
    switch (colorMode) {
        case ui::ColorMode::DISPLAY_P3:
        case ui::ColorMode::DISPLAY_P3:
@@ -2032,6 +2040,29 @@ static jlong getNativeTrustedPresentationCallbackFinalizer(JNIEnv* env, jclass c
    return static_cast<jlong>(reinterpret_cast<uintptr_t>(&destroyNativeTpc));
    return static_cast<jlong>(reinterpret_cast<uintptr_t>(&destroyNativeTpc));
}
}


static jobject nativeGetStalledTransactionInfo(JNIEnv* env, jclass clazz, jint pid) {
    std::optional<gui::StalledTransactionInfo> stalledTransactionInfo =
            SurfaceComposerClient::getStalledTransactionInfo(pid);
    if (!stalledTransactionInfo) {
        return nullptr;
    }

    jobject jStalledTransactionInfo = env->NewObject(gStalledTransactionInfoClassInfo.clazz,
                                                     gStalledTransactionInfoClassInfo.ctor);
    if (!jStalledTransactionInfo) {
        jniThrowException(env, "java/lang/OutOfMemoryError", nullptr);
        return nullptr;
    }

    env->SetObjectField(jStalledTransactionInfo, gStalledTransactionInfoClassInfo.layerName,
                        env->NewStringUTF(String8{stalledTransactionInfo->layerName}));
    env->SetLongField(jStalledTransactionInfo, gStalledTransactionInfoClassInfo.bufferId,
                      static_cast<jlong>(stalledTransactionInfo->bufferId));
    env->SetLongField(jStalledTransactionInfo, gStalledTransactionInfoClassInfo.frameNumber,
                      static_cast<jlong>(stalledTransactionInfo->frameNumber));
    return jStalledTransactionInfo;
}

// ----------------------------------------------------------------------------
// ----------------------------------------------------------------------------


SurfaceControl* android_view_SurfaceControl_getNativeSurfaceControl(JNIEnv* env,
SurfaceControl* android_view_SurfaceControl_getNativeSurfaceControl(JNIEnv* env,
@@ -2281,6 +2312,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = {
    {"nativeCreateTpc", "(Landroid/view/SurfaceControl$TrustedPresentationCallback;)J",
    {"nativeCreateTpc", "(Landroid/view/SurfaceControl$TrustedPresentationCallback;)J",
            (void*)nativeCreateTpc},
            (void*)nativeCreateTpc},
    {"getNativeTrustedPresentationCallbackFinalizer", "()J", (void*)getNativeTrustedPresentationCallbackFinalizer },
    {"getNativeTrustedPresentationCallbackFinalizer", "()J", (void*)getNativeTrustedPresentationCallbackFinalizer },
    {"nativeGetStalledTransactionInfo", "(I)Landroid/gui/StalledTransactionInfo;",
            (void*) nativeGetStalledTransactionInfo },
        // clang-format on
        // clang-format on
};
};


@@ -2524,6 +2557,18 @@ int register_android_view_SurfaceControl(JNIEnv* env)
    gTrustedPresentationCallbackClassInfo.onTrustedPresentationChanged =
    gTrustedPresentationCallbackClassInfo.onTrustedPresentationChanged =
            GetMethodIDOrDie(env, trustedPresentationCallbackClazz, "onTrustedPresentationChanged",
            GetMethodIDOrDie(env, trustedPresentationCallbackClazz, "onTrustedPresentationChanged",
                             "(Z)V");
                             "(Z)V");

    jclass stalledTransactionInfoClazz = FindClassOrDie(env, "android/gui/StalledTransactionInfo");
    gStalledTransactionInfoClassInfo.clazz = MakeGlobalRefOrDie(env, stalledTransactionInfoClazz);
    gStalledTransactionInfoClassInfo.ctor =
            GetMethodIDOrDie(env, stalledTransactionInfoClazz, "<init>", "()V");
    gStalledTransactionInfoClassInfo.layerName =
            GetFieldIDOrDie(env, stalledTransactionInfoClazz, "layerName", "Ljava/lang/String;");
    gStalledTransactionInfoClassInfo.bufferId =
            GetFieldIDOrDie(env, stalledTransactionInfoClazz, "bufferId", "J");
    gStalledTransactionInfoClassInfo.frameNumber =
            GetFieldIDOrDie(env, stalledTransactionInfoClazz, "frameNumber", "J");

    return err;
    return err;
}
}


+17 −6
Original line number Original line Diff line number Diff line
@@ -25,6 +25,7 @@ import static com.android.server.wm.WindowManagerService.H.ON_POINTER_DOWN_OUTSI


import android.annotation.NonNull;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Nullable;
import android.gui.StalledTransactionInfo;
import android.os.Debug;
import android.os.Debug;
import android.os.IBinder;
import android.os.IBinder;
import android.util.Slog;
import android.util.Slog;
@@ -96,7 +97,7 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal
    @Override
    @Override
    public void notifyNoFocusedWindowAnr(@NonNull InputApplicationHandle applicationHandle) {
    public void notifyNoFocusedWindowAnr(@NonNull InputApplicationHandle applicationHandle) {
        TimeoutRecord timeoutRecord = TimeoutRecord.forInputDispatchNoFocusedWindow(
        TimeoutRecord timeoutRecord = TimeoutRecord.forInputDispatchNoFocusedWindow(
                timeoutMessage("Application does not have a focused window"));
                timeoutMessage(OptionalInt.empty(), "Application does not have a focused window"));
        mService.mAnrController.notifyAppUnresponsive(applicationHandle, timeoutRecord);
        mService.mAnrController.notifyAppUnresponsive(applicationHandle, timeoutRecord);
    }
    }


@@ -104,7 +105,7 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal
    public void notifyWindowUnresponsive(@NonNull IBinder token, @NonNull OptionalInt pid,
    public void notifyWindowUnresponsive(@NonNull IBinder token, @NonNull OptionalInt pid,
            String reason) {
            String reason) {
        TimeoutRecord timeoutRecord = TimeoutRecord.forInputDispatchWindowUnresponsive(
        TimeoutRecord timeoutRecord = TimeoutRecord.forInputDispatchWindowUnresponsive(
                timeoutMessage(reason));
                timeoutMessage(pid, reason));
        mService.mAnrController.notifyWindowUnresponsive(token, pid, timeoutRecord);
        mService.mAnrController.notifyWindowUnresponsive(token, pid, timeoutRecord);
    }
    }


@@ -354,11 +355,21 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal
        mService.mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
        mService.mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen);
    }
    }


    private String timeoutMessage(String reason) {
    private String timeoutMessage(OptionalInt pid, String reason) {
        if (reason == null) {
        String message = (reason == null) ? "Input dispatching timed out."
            return "Input dispatching timed out";
                : String.format("Input dispatching timed out (%s).", reason);
        if (pid.isEmpty()) {
            return message;
        }
        }
        return "Input dispatching timed out (" + reason + ")";
        StalledTransactionInfo stalledTransactionInfo =
                SurfaceControl.getStalledTransactionInfo(pid.getAsInt());
        if (stalledTransactionInfo == null) {
            return message;
        }
        return String.format("%s Buffer processing for the associated surface is stuck due to an "
                + "unsignaled fence (window=%s, bufferId=0x%016X, frameNumber=%s). This "
                + "potentially indicates a GPU hang.", message, stalledTransactionInfo.layerName,
                stalledTransactionInfo.bufferId, stalledTransactionInfo.frameNumber);
    }
    }


    void dump(PrintWriter pw, String prefix) {
    void dump(PrintWriter pw, String prefix) {