6060 * The restore token allows the ScreenCast session to be restored
6161 * with previously granted screen access permissions.
6262 */
63- @ SuppressWarnings ("removal" )
6463final class TokenStorage {
6564
6665 private TokenStorage () {}
6766
6867 private static final String REL_NAME =
68+ ".java/robot/screencast-tokens.properties" ;
69+ private static final String REL_NAME_SECONDARY =
6970 ".awt/robot/screencast-tokens.properties" ;
7071
7172 private static final Properties PROPS = new Properties ();
7273 private static final Path PROPS_PATH ;
7374 private static final Path PROP_FILENAME ;
7475
76+ @ SuppressWarnings ("removal" )
7577 private static void doPrivilegedRunnable (Runnable runnable ) {
76- AccessController .doPrivileged (new PrivilegedAction <Void >() {
77- @ Override
78- public Void run () {
79- runnable .run ();
80- return null ;
81- }
78+ AccessController .doPrivileged ((PrivilegedAction <Void >) () -> {
79+ runnable .run ();
80+ return null ;
8281 });
8382 }
8483
8584 static {
86- PROPS_PATH = AccessController .doPrivileged (new PrivilegedAction <Path >() {
87- @ Override
88- public Path run () {
89- return setupPath ();
90- }
91- });
85+ @ SuppressWarnings ("removal" )
86+ Path propsPath = AccessController
87+ .doPrivileged ((PrivilegedAction <Path >) () -> setupPath ());
88+
89+ PROPS_PATH = propsPath ;
9290
9391 if (PROPS_PATH != null ) {
9492 PROP_FILENAME = PROPS_PATH .getFileName ();
@@ -110,25 +108,32 @@ private static Path setupPath() {
110108 }
111109
112110 Path path = Path .of (userHome , REL_NAME );
111+ Path secondaryPath = Path .of (userHome , REL_NAME_SECONDARY );
112+
113+ boolean copyFromSecondary = !Files .isWritable (path )
114+ && Files .isWritable (secondaryPath );
115+
113116 Path workdir = path .getParent ();
114117
115- if (!Files .exists (workdir )) {
116- try {
117- Files .createDirectories (workdir );
118- } catch (Exception e ) {
119- if (SCREENCAST_DEBUG ) {
120- System .err .printf ("Token storage: cannot create" +
121- " directory %s %s\n " , workdir , e );
118+ if (!Files .isWritable (path )) {
119+ if (!Files .exists (workdir )) {
120+ try {
121+ Files .createDirectories (workdir );
122+ } catch (Exception e ) {
123+ if (SCREENCAST_DEBUG ) {
124+ System .err .printf ("Token storage: cannot create" +
125+ " directory %s %s\n " , workdir , e );
126+ }
127+ return null ;
122128 }
123- return null ;
124129 }
125- }
126130
127- if (!Files .isWritable (workdir )) {
128- if (SCREENCAST_DEBUG ) {
129- System .err .printf ("Token storage: %s is not writable\n " , workdir );
131+ if (!Files .isWritable (workdir )) {
132+ if (SCREENCAST_DEBUG ) {
133+ System .err .printf ("Token storage: %s is not writable\n " , workdir );
134+ }
135+ return null ;
130136 }
131- return null ;
132137 }
133138
134139 try {
@@ -145,7 +150,17 @@ private static Path setupPath() {
145150 }
146151 }
147152
148- if (Files .exists (path )) {
153+ if (copyFromSecondary ) {
154+ if (SCREENCAST_DEBUG ) {
155+ System .out .println ("Token storage: copying from the secondary location "
156+ + secondaryPath );
157+ }
158+ synchronized (PROPS ) {
159+ if (readTokens (secondaryPath )) {
160+ store (path , "copy from the secondary location" );
161+ }
162+ }
163+ } else if (Files .exists (path )) {
149164 if (!setFilePermission (path )) {
150165 return null ;
151166 }
@@ -302,7 +317,7 @@ private static void storeTokenFromNative(String oldToken,
302317 }
303318
304319 if (changed ) {
305- doPrivilegedRunnable (() -> store ("save tokens" ));
320+ doPrivilegedRunnable (() -> store (PROPS_PATH , "save tokens" ));
306321 }
307322 }
308323 }
@@ -315,7 +330,7 @@ private static boolean readTokens(Path path) {
315330 PROPS .clear ();
316331 PROPS .load (reader );
317332 }
318- } catch (IOException e ) {
333+ } catch (IOException | IllegalArgumentException e ) {
319334 if (SCREENCAST_DEBUG ) {
320335 System .err .printf ("""
321336 Token storage: failed to load property file %s
@@ -410,7 +425,7 @@ static Set<TokenItem> getTokens(List<Rectangle> affectedScreenBounds) {
410425 }
411426
412427 private static void removeMalformedRecords (Set <String > malformedRecords ) {
413- if (!isWritable ()
428+ if (!isWritable (PROPS_PATH )
414429 || malformedRecords == null
415430 || malformedRecords .isEmpty ()) {
416431 return ;
@@ -424,17 +439,17 @@ private static void removeMalformedRecords(Set<String> malformedRecords) {
424439 }
425440 }
426441
427- store ("remove malformed records" );
442+ store (PROPS_PATH , "remove malformed records" );
428443 }
429444 }
430445
431- private static void store (String failMsg ) {
432- if (!isWritable ()) {
446+ private static void store (Path path , String failMsg ) {
447+ if (!isWritable (path )) {
433448 return ;
434449 }
435450
436451 synchronized (PROPS ) {
437- try (BufferedWriter writer = Files .newBufferedWriter (PROPS_PATH )) {
452+ try (BufferedWriter writer = Files .newBufferedWriter (path )) {
438453 PROPS .store (writer , null );
439454 } catch (IOException e ) {
440455 if (SCREENCAST_DEBUG ) {
@@ -445,13 +460,13 @@ private static void store(String failMsg) {
445460 }
446461 }
447462
448- private static boolean isWritable () {
449- if (PROPS_PATH == null
450- || (Files .exists (PROPS_PATH ) && !Files .isWritable (PROPS_PATH ))) {
463+ private static boolean isWritable (Path path ) {
464+ if (path == null
465+ || (Files .exists (path ) && !Files .isWritable (path ))) {
451466
452467 if (SCREENCAST_DEBUG ) {
453468 System .err .printf (
454- "Token storage: %s is not writable\n " , PROPS_PATH );
469+ "Token storage: %s is not writable\n " , path );
455470 }
456471 return false ;
457472 } else {
0 commit comments