RFR: 8280982: [Wayland] [XWayland] java.awt.Robot taking screenshots [v2]
Alexander Zvegintsev
azvegint at openjdk.org
Tue May 9 22:12:15 UTC 2023
On Tue, 9 May 2023 20:43:13 GMT, Phil Race <prr at openjdk.org> wrote:
> I want to work through the scenarios and how much of it is specific to the behaviours of the API you are using and so forth. Since you use the Preferences API for saving the token, if you keyed it off the Robot class rather than the internal API class then anyone using the Preferences API could delete the token, couldn't they ?
Right now it can be read with a simple call:
`System.out.println(Preferences.userRoot().node("/sun/awt/screencast").get("restoreToken", ""));` (modification is also simple).
Moving to Robot doesn't change anything in this regard. So anyone can delete it.
> And we presumably can store alongside the token, info about the screens attached at the time we obtained the token ?
We can try to do that and switch it depending on the area requested, but I tried to keep it simple.
> Can you point (here in the implementation review) to the exact native functions that popup up the dialog ? I'm still trying to find my way through that code. Is it opaque to the caller (us) what the user actually approved ?
(It is collapsed by the github in the review, so links are to the branch)
basically if you [didn't provide a correct token or no token at all](https://github.com/azvegint/jdk/blob/482471df61490120590bc49886f76dc99c3d7dd8/src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.c#L530-L537) to [SelectSources call](https://github.com/azvegint/jdk/blob/482471df61490120590bc49886f76dc99c3d7dd8/src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.c#L539-L546) it will prompt with dialog right after [the Start call](https://github.com/azvegint/jdk/blob/482471df61490120590bc49886f76dc99c3d7dd8/src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.c#L677-L685)
> I can't imagine why we would need to reset "we have all permissions" to "we have no permissions" so I'm supposing the issue is when they didn't grant permissions .. but if they "deny" permissions that's surely different than "this token is no longer valid" ?
It is not for the "we have all permissions" case, it is for the case when we only have a permission to some screens. So it won't hurt.
> The first time we need a permission for the screencast API there is a dialog. The user makes some choices and we then choose to save a token so that the user isn't prompted again. We must at least know though that they approved SOMETHING but we don't know what ? Or do we ?
No we don't.
We receive the response [callbackScreenCastStart](https://github.com/azvegint/jdk/blob/482471df61490120590bc49886f76dc99c3d7dd8/src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.c#L586-L591) as a separate streams for each allowed display.
Based on this response we [building a list of **available** displays](https://github.com/azvegint/jdk/blob/482471df61490120590bc49886f76dc99c3d7dd8/src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.c#L73).
So denied screens will not be there.
At this point we can compare this result with the screens got from X11 API(won't be compatible with Wayland, where we also want to reuse it later) or with Wayland(+1 dependency at this point).
> If they DENY, would we save that ? Interesting question because if we don't save something we'll keep spamming them until they approve :-)
The [DENY case](https://github.com/azvegint/jdk/blob/482471df61490120590bc49886f76dc99c3d7dd8/src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.c#L586-L591) propagated to java and we are throwing the security exception.
> Next time, what happens if for some reaon the token is no longer valid ?
It just prompts a permission request again.
> And what might make it invalid ?
Adding or removing a display for example.
> If the user denied screen 2, or added screen 2 later, would that not result in an invalid token and we'd know to ask again ? No reset needed ? Also I can't figure out if "validating" the token can cause the dialog as a side effect or if there's some API we explicitly call to request a new token.
Let me elaborate how this `restore_token` works:
We may or may not provide the `restore_token` while calling `SelectSources`.
If the token provided is not valid (we have no control over this, it's checked on the system side), the permission prompt will appear.
Later, after granting permissions, the `restore_token` is returned by [Start](https://flatpak.github.io/xdg-desktop-portal/#gdbus-method-org-freedesktop-portal-ScreenCast.Start) callback. We should [update](https://github.com/azvegint/jdk/blob/482471df61490120590bc49886f76dc99c3d7dd8/src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.c#L593-L611) it, as it may not be the same as we provided before.
When we are calling the `resetScreenCapturePermission` we are not actually revoking the token from the system, we are just doesn't add it to the `SelectSources` call. (but, if needed, we can provide it later and it should work).
So whenever we don't provide a valid token, we get a confirmation prompt.
-------------
PR Comment: https://git.openjdk.org/jdk/pull/13803#issuecomment-1540951957
More information about the build-dev
mailing list