Loading core/java/android/view/SurfaceControl.java +9 −0 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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); } } } core/jni/android_view_SurfaceControl.cpp +45 −0 Original line number Original line Diff line number Diff line Loading @@ -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: Loading Loading @@ -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, Loading Loading @@ -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 }; }; Loading Loading @@ -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; } } Loading services/core/java/com/android/server/wm/InputManagerCallback.java +17 −6 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } Loading @@ -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); } } Loading Loading @@ -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) { Loading Loading
core/java/android/view/SurfaceControl.java +9 −0 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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. Loading Loading @@ -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); } } }
core/jni/android_view_SurfaceControl.cpp +45 −0 Original line number Original line Diff line number Diff line Loading @@ -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: Loading Loading @@ -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, Loading Loading @@ -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 }; }; Loading Loading @@ -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; } } Loading
services/core/java/com/android/server/wm/InputManagerCallback.java +17 −6 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } Loading @@ -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); } } Loading Loading @@ -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) { Loading