RFR: 8280982: [Wayland] [XWayland] java.awt.Robot taking screenshots [v11]
Prasanta Sadhukhan
psadhukhan at openjdk.org
Wed Jun 7 05:28:16 UTC 2023
On Wed, 7 Jun 2023 01:27:50 GMT, Alexander Zvegintsev <azvegint at openjdk.org> wrote:
>> Modern Linux systems often come with [Wayland](https://wayland.freedesktop.org/) by default.
>> This comes with some difficulties, and one of them is the inability to get screenshots from the system.
>> This is because we now use the [X Window System API](https://en.wikipedia.org/wiki/X_Window_System) to capture screenshots and it cannot access data outside the [XWayland server](https://wayland.freedesktop.org/xserver.html)
>>
>> But this functionality is a very important part of automated testing.
>>
>>
>> At the moment there are two obvious solutions to this problem, and both use [xdg-desktop-portal](https://github.com/flatpak/xdg-desktop-portal):
>>
>> 1. [org.freedesktop.portal.Screenshot DBUS API](https://flatpak.github.io/xdg-desktop-portal/#gdbus-org.freedesktop.portal.Screenshot)
>> It has several drawbacks though:
>> + It saves a screenshot to disk, which must be read and deleted(may add some delays depending on the type of a disk drive).
>> + There is no way to disable the visual "screen flash" after screenshot
>> + It asks a user confirmation to save a screenshot. This confirmation can be saved on Gnome 43+.
>> Since we would like Ubuntu 22.04 LTS which comes with Gnome 42 this option is not acceptable for us because it would require user confirmation for each screenshot.
>> But we still can consider this option as a fallback.
>>
>>
>>
>> 2. [org.freedesktop.portal.ScreenCast](https://flatpak.github.io/xdg-desktop-portal/#gdbus-org.freedesktop.portal.ScreenCast)
>> It typically used by applications that need to capture the contents of the user's screen or a specific window for the purpose of sharing, recording, or streaming.
>> This might be a bit of overkill, but it avoids several of the problems mentioned in the Screenshot API.
>>
>> + implementation is more complicated comparing to Screenshot API
>> + no intermediate file, screenshot data can be obtained from memory
>> + Permission to make screenshots can be stored with [`restore_token`](https://flatpak.github.io/xdg-desktop-portal/#gdbus-method-org-freedesktop-portal-ScreenCast.SelectSources)
>>
>>
>> So this PR adds the ability to take screenshots using the ScreenCast API. This functionality is currently disabled by default.
>>
>> This change also introduces some new behavior for the robot:
>> A system window now appears asking for confirmation from the user to capture the screen.
>> + The user can refuse the screen capture completely. In this case a security exception will be thrown.
>> + The user can allow...
>
> Alexander Zvegintsev has updated the pull request incrementally with two additional commits since the last revision:
>
> - move screencast-tokens.properties to a new location
> - fix failure of javax/swing/reliability/HangDuringStaticInitialization.java in headless environment
Mostly alignment issue with couple of code comments..
src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java line 53:
> 51:
> 52: tryGtk = Boolean.parseBoolean(
> 53: AccessController.doPrivileged(
Code formatting..better to align `AccessController `below `Boolean`
src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java line 69:
> 67: isOnWayland
> 68: ? METHOD_SCREENCAST
> 69: : METHOD_X11
code alignment issue...will look better if all starts in same column
src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java line 126:
> 124: int[] pixelArray = new int[1];
> 125: if (screenshotMethod.equals(METHOD_SCREENCAST)
> 126: && ScreencastHelper.isAvailable()) {
align `&&` below `screenshotMethod`
src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java line 138:
> 136: int[] pixelArray = new int[bounds.width * bounds.height];
> 137: if (screenshotMethod.equals(METHOD_SCREENCAST)
> 138: && ScreencastHelper.isAvailable()) {
same here
src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java line 142:
> 140: bounds.x, bounds.y,
> 141: bounds.width, bounds.height,
> 142: pixelArray
you can align below the brace ( as it will not cross 80 chars, I believe
src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java line 150:
> 148: bounds.width, bounds.height,
> 149: pixelArray, useGtk
> 150: );
same here
src/java.desktop/unix/classes/sun/awt/screencast/ScreencastHelper.java line 63:
> 61: SCREENCAST_DEBUG = Boolean.parseBoolean(
> 62: AccessController.doPrivileged(
> 63: new GetPropertyAction(
align AccessController below Boolean
src/java.desktop/unix/classes/sun/awt/screencast/ScreencastHelper.java line 72:
> 70:
> 71: if (!(Toolkit.getDefaultToolkit()
> 72: instanceof UNIXToolkit tk && tk.loadGTK())
I guess better to move `Toolkit.getDefaultToolkit() instance UNIXToolkit tk` in same line and align `&& `below Toolkit
src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java line 145:
> 143: path,
> 144: Set.of(PosixFilePermission.OWNER_READ,
> 145: PosixFilePermission.OWNER_WRITE)
alignment issue..Posix..OWNER_WRITE should be placed below Posix..OENER_READ
Also, why we aren't adding OWNER_EXECUTE here too like done above?
src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java line 316:
> 314: allTokenItems = PROPS.entrySet()
> 315: .stream()
> 316: .map(o -> {
align below PROPS
src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java line 335:
> 333: if (tokenItem != null
> 334: && tokenItem
> 335: .hasAllScreensWithExactMatch(affectedScreenBounds)) {
align below `tokenItem`
src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java line 350:
> 348: .map(rectangle -> new Dimension(
> 349: rectangle.width,
> 350: rectangle.height
align below `affectedScreenBounds`
src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java line 356:
> 354: for (TokenItem tokenItem : allTokenItems) {
> 355: if (tokenItem != null
> 356: && tokenItem.hasAllScreensOfSameSize(dimensions)) {
align below `tokenItem`
src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java line 371:
> 369: if (!isWritable()
> 370: || malformedRecords == null
> 371: || malformedRecords.isEmpty()) {
align below `isWritable`
src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java line 406:
> 404: private static boolean isWritable() {
> 405: if (PROPS_PATH == null
> 406: || (Files.exists(PROPS_PATH) && !Files.isWritable(PROPS_PATH))) {
align below PROPS_PATH
src/java.desktop/unix/native/libawt_xawt/awt/gtk2_interface.h line 94:
> 92: gint width;
> 93: gint height;
> 94: } GdkRectangle;
Any reason why it is removed? I think it's needed in gtk2_interface.c, right?
Probably we can delete from gtk3_interface.h as it is not used in gtk3_interface.c
src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c line 674:
> 672: EXCEPTION_CHECK_DESCRIBE();
> 673: if (!allowedBounds) {
> 674: (*env)->ExceptionClear(env);
I guess as mentioned above, DESCRIBE clears exception also so no need of calling explicit Clear
https://docs.oracle.com/en/java/javase/17/docs/specs/jni/functions.html#exceptiondescribe
src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c line 694:
> 692: if ((*env)->ExceptionCheck(env)) {
> 693: (*env)->ExceptionDescribe(env);
> 694: (*env)->ExceptionClear(env);
same here
-------------
Marked as reviewed by psadhukhan (Reviewer).
PR Review: https://git.openjdk.org/jdk/pull/13803#pullrequestreview-1466590673
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220836005
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220836075
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220836350
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220836410
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220837445
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220837512
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220838239
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220839222
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220853099
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220853881
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220854061
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220854228
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220854400
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220854551
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220854760
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220857001
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220864748
PR Review Comment: https://git.openjdk.org/jdk/pull/13803#discussion_r1220865107
More information about the build-dev
mailing list