diff options
-rw-r--r-- | core/java/android/view/SurfaceControl.java | 9 | ||||
-rw-r--r-- | core/jni/android_view_SurfaceControl.cpp | 45 | ||||
-rw-r--r-- | services/core/java/com/android/server/wm/InputManagerCallback.java | 23 |
3 files changed, 71 insertions, 6 deletions
diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index c11f4975149d..e67367639514 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -47,6 +47,7 @@ import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; import android.gui.DropInputMode; +import android.gui.StalledTransactionInfo; import android.hardware.DataSpace; import android.hardware.HardwareBuffer; import android.hardware.OverlayProperties; @@ -292,6 +293,7 @@ public final class SurfaceControl implements Parcelable { long nativeObject, long nativeTpc, TrustedPresentationThresholds thresholds); private static native void nativeClearTrustedPresentationCallback(long transactionObj, long nativeObject); + private static native StalledTransactionInfo nativeGetStalledTransactionInfo(int pid); /** * 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); } + /** + * @hide + */ + public static StalledTransactionInfo getStalledTransactionInfo(int pid) { + return nativeGetStalledTransactionInfo(pid); + } + } diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 424925328dfd..dbe03386a9cf 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -257,6 +257,14 @@ static struct { jmethodID onTrustedPresentationChanged; } gTrustedPresentationCallbackClassInfo; +static struct { + jclass clazz; + jmethodID ctor; + jfieldID layerName; + jfieldID bufferId; + jfieldID frameNumber; +} gStalledTransactionInfoClassInfo; + constexpr ui::Dataspace pickDataspaceFromColorMode(const ui::ColorMode colorMode) { switch (colorMode) { 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)); } +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, @@ -2281,6 +2312,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = { {"nativeCreateTpc", "(Landroid/view/SurfaceControl$TrustedPresentationCallback;)J", (void*)nativeCreateTpc}, {"getNativeTrustedPresentationCallbackFinalizer", "()J", (void*)getNativeTrustedPresentationCallbackFinalizer }, + {"nativeGetStalledTransactionInfo", "(I)Landroid/gui/StalledTransactionInfo;", + (void*) nativeGetStalledTransactionInfo }, // clang-format on }; @@ -2524,6 +2557,18 @@ int register_android_view_SurfaceControl(JNIEnv* env) gTrustedPresentationCallbackClassInfo.onTrustedPresentationChanged = GetMethodIDOrDie(env, trustedPresentationCallbackClazz, "onTrustedPresentationChanged", "(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; } diff --git a/services/core/java/com/android/server/wm/InputManagerCallback.java b/services/core/java/com/android/server/wm/InputManagerCallback.java index 20595eaa1e3c..73fdfe0d1181 100644 --- a/services/core/java/com/android/server/wm/InputManagerCallback.java +++ b/services/core/java/com/android/server/wm/InputManagerCallback.java @@ -25,6 +25,7 @@ import static com.android.server.wm.WindowManagerService.H.ON_POINTER_DOWN_OUTSI import android.annotation.NonNull; import android.annotation.Nullable; +import android.gui.StalledTransactionInfo; import android.os.Debug; import android.os.IBinder; import android.util.Slog; @@ -96,7 +97,7 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal @Override public void notifyNoFocusedWindowAnr(@NonNull InputApplicationHandle applicationHandle) { 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); } @@ -104,7 +105,7 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal public void notifyWindowUnresponsive(@NonNull IBinder token, @NonNull OptionalInt pid, String reason) { TimeoutRecord timeoutRecord = TimeoutRecord.forInputDispatchWindowUnresponsive( - timeoutMessage(reason)); + timeoutMessage(pid, reason)); mService.mAnrController.notifyWindowUnresponsive(token, pid, timeoutRecord); } @@ -354,11 +355,21 @@ final class InputManagerCallback implements InputManagerService.WindowManagerCal mService.mInputManager.setInputDispatchMode(mInputDispatchEnabled, mInputDispatchFrozen); } - private String timeoutMessage(String reason) { - if (reason == null) { - return "Input dispatching timed out"; + private String timeoutMessage(OptionalInt pid, String reason) { + String message = (reason == null) ? "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) { |