diff options
author | Victor Chang <vichang@google.com> | 2024-02-14 17:47:44 +0000 |
---|---|---|
committer | Victor Chang <vichang@google.com> | 2024-02-14 21:09:10 +0000 |
commit | d09e3b41d2724730c4762462bd1d9ad1afa8efa6 (patch) | |
tree | a9f29f5c35e8b60b7520426af0bede84aa538390 | |
parent | a7c93248cfe462e9f0208133e9233a2b32101698 (diff) | |
parent | e0544eb85f5abcd99df02874f61e95f5d440a81d (diff) | |
download | libcore-d09e3b41d2724730c4762462bd1d9ad1afa8efa6.tar.gz |
Merge Console from jdk-17.0.10-ga into the aosp/main branch
List of files:
ojluni/src/main/java/java/io/Console.java
Bug: 270692319
Test: N/A
Change-Id: I07c5843aa577f5b77ac87dd7f6a556e0b6c9d425
-rw-r--r-- | EXPECTED_UPSTREAM | 2 | ||||
-rw-r--r-- | api/current.txt | 1 | ||||
-rw-r--r-- | luni/src/test/java/libcore/java/io/ConsoleTest.java | 11 | ||||
-rw-r--r-- | ojluni/annotations/flagged_api/java/io/Console.annotated.java | 56 | ||||
-rw-r--r-- | ojluni/src/main/java/java/io/Console.java | 168 |
5 files changed, 197 insertions, 41 deletions
diff --git a/EXPECTED_UPSTREAM b/EXPECTED_UPSTREAM index 7158588f6b8..41b2f211c52 100644 --- a/EXPECTED_UPSTREAM +++ b/EXPECTED_UPSTREAM @@ -40,7 +40,7 @@ ojluni/src/main/java/java/io/CharArrayReader.java,jdk11u/jdk-11.0.13-ga,src/java ojluni/src/main/java/java/io/CharArrayWriter.java,jdk11u/jdk-11.0.13-ga,src/java.base/share/classes/java/io/CharArrayWriter.java ojluni/src/main/java/java/io/CharConversionException.java,jdk17u/jdk-17.0.6-ga,src/java.base/share/classes/java/io/CharConversionException.java ojluni/src/main/java/java/io/Closeable.java,jdk17u/jdk-17.0.6-ga,src/java.base/share/classes/java/io/Closeable.java -ojluni/src/main/java/java/io/Console.java,jdk8u/jdk8u121-b13,jdk/src/share/classes/java/io/Console.java +ojluni/src/main/java/java/io/Console.java,jdk17u/jdk-17.0.10-ga,src/java.base/share/classes/java/io/Console.java ojluni/src/main/java/java/io/DataInput.java,jdk11u/jdk-11.0.13-ga,src/java.base/share/classes/java/io/DataInput.java ojluni/src/main/java/java/io/DataInputStream.java,jdk11u/jdk-11.0.13-ga,src/java.base/share/classes/java/io/DataInputStream.java ojluni/src/main/java/java/io/DataOutput.java,jdk11u/jdk-11.0.13-ga,src/java.base/share/classes/java/io/DataOutput.java diff --git a/api/current.txt b/api/current.txt index 3a3771eb695..331fd46637e 100644 --- a/api/current.txt +++ b/api/current.txt @@ -1420,6 +1420,7 @@ package java.io { } public final class Console implements java.io.Flushable { + method @FlaggedApi("com.android.libcore.v_apis") public java.nio.charset.Charset charset(); method public void flush(); method public java.io.Console format(String, java.lang.Object...); method public java.io.Console printf(String, java.lang.Object...); diff --git a/luni/src/test/java/libcore/java/io/ConsoleTest.java b/luni/src/test/java/libcore/java/io/ConsoleTest.java index 36d382f08dd..2e2aa7b9678 100644 --- a/luni/src/test/java/libcore/java/io/ConsoleTest.java +++ b/luni/src/test/java/libcore/java/io/ConsoleTest.java @@ -28,6 +28,7 @@ import java.io.IOError; import java.io.InputStream; import java.io.OutputStream; import java.lang.reflect.Constructor; +import java.nio.charset.StandardCharsets; import org.junit.Test; import org.junit.runner.RunWith; @@ -95,4 +96,14 @@ public final class ConsoleTest { } } + @Test + public void testCharset() throws Exception { + final byte[] bytes = "secret password\n".getBytes(); + ByteArrayInputStream inStream = new ByteArrayInputStream(bytes); + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + Console console = createConsole(inStream, outStream); + // Android uses UTF-8 as the default charset. + assertEquals(StandardCharsets.UTF_8, console.charset()); + } + } diff --git a/ojluni/annotations/flagged_api/java/io/Console.annotated.java b/ojluni/annotations/flagged_api/java/io/Console.annotated.java new file mode 100644 index 00000000000..d4da84a0b77 --- /dev/null +++ b/ojluni/annotations/flagged_api/java/io/Console.annotated.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + + +package java.io; + +@SuppressWarnings({"unchecked", "deprecation", "all"}) +public final class Console implements java.io.Flushable { + +Console() { throw new RuntimeException("Stub!"); } + +public java.io.PrintWriter writer() { throw new RuntimeException("Stub!"); } + +public java.io.Reader reader() { throw new RuntimeException("Stub!"); } + +public java.io.Console format(java.lang.String fmt, java.lang.Object... args) { throw new RuntimeException("Stub!"); } + +public java.io.Console printf(java.lang.String format, java.lang.Object... args) { throw new RuntimeException("Stub!"); } + +public java.lang.String readLine(java.lang.String fmt, java.lang.Object... args) { throw new RuntimeException("Stub!"); } + +public java.lang.String readLine() { throw new RuntimeException("Stub!"); } + +public char[] readPassword(java.lang.String fmt, java.lang.Object... args) { throw new RuntimeException("Stub!"); } + +public char[] readPassword() { throw new RuntimeException("Stub!"); } + +public void flush() { throw new RuntimeException("Stub!"); } + +@android.annotation.FlaggedApi(com.android.libcore.Flags.FLAG_V_APIS) +public java.nio.charset.Charset charset() { throw new RuntimeException("Stub!"); } +} + diff --git a/ojluni/src/main/java/java/io/Console.java b/ojluni/src/main/java/java/io/Console.java index b25759c4210..5a21ff52904 100644 --- a/ojluni/src/main/java/java/io/Console.java +++ b/ojluni/src/main/java/java/io/Console.java @@ -1,6 +1,6 @@ /* * Copyright (C) 2014 The Android Open Source Project - * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,10 @@ package java.io; import java.util.*; import java.nio.charset.Charset; +import jdk.internal.access.SharedSecrets; import sun.nio.cs.StreamDecoder; import sun.nio.cs.StreamEncoder; +import sun.security.action.GetPropertyAction; /** * Methods to access the character-based console device, if any, associated @@ -48,7 +50,7 @@ import sun.nio.cs.StreamEncoder; * If this virtual machine has a console then it is represented by a * unique instance of this class which can be obtained by invoking the * {@link java.lang.System#console()} method. If no console device is - * available then an invocation of that method will return <tt>null</tt>. + * available then an invocation of that method will return {@code null}. * <p> * Read and write operations are synchronized to guarantee the atomic * completion of critical operations; therefore invoking methods @@ -57,17 +59,17 @@ import sun.nio.cs.StreamEncoder; * on the objects returned by {@link #reader()} and {@link #writer()} may * block in multithreaded scenarios. * <p> - * Invoking <tt>close()</tt> on the objects returned by the {@link #reader()} + * Invoking {@code close()} on the objects returned by the {@link #reader()} * and the {@link #writer()} will not close the underlying stream of those * objects. * <p> - * The console-read methods return <tt>null</tt> when the end of the + * The console-read methods return {@code null} when the end of the * console input stream is reached, for example by typing control-D on * Unix or control-Z on Windows. Subsequent read operations will succeed * if additional characters are later entered on the console's input * device. * <p> - * Unless otherwise specified, passing a <tt>null</tt> argument to any method + * Unless otherwise specified, passing a {@code null} argument to any method * in this class will cause a {@link NullPointerException} to be thrown. * <p> * <b>Security note:</b> @@ -108,7 +110,7 @@ public final class Console implements Flushable * <p> * This method is intended to be used by sophisticated applications, for * example, a {@link java.util.Scanner} object which utilizes the rich - * parsing/scanning functionality provided by the <tt>Scanner</tt>: + * parsing/scanning functionality provided by the {@code Scanner}: * <blockquote><pre> * Console con = System.console(); * if (con != null) { @@ -118,7 +120,7 @@ public final class Console implements Flushable * </pre></blockquote> * <p> * For simple applications requiring only line-oriented reading, use - * <tt>{@link #readLine}</tt>. + * {@link #readLine}. * <p> * The bulk read operations {@link java.io.Reader#read(char[]) read(char[]) }, * {@link java.io.Reader#read(char[], int, int) read(char[], int, int) } and @@ -127,8 +129,8 @@ public final class Console implements Flushable * bound for each invocation, even if the destination buffer has space for * more characters. The {@code Reader}'s {@code read} methods may block if a * line bound has not been entered or reached on the console's input device. - * A line bound is considered to be any one of a line feed (<tt>'\n'</tt>), - * a carriage return (<tt>'\r'</tt>), a carriage return followed immediately + * A line bound is considered to be any one of a line feed ({@code '\n'}), + * a carriage return ({@code '\r'}), a carriage return followed immediately * by a linefeed, or an end of stream. * * @return The reader associated with this console @@ -151,9 +153,9 @@ public final class Console implements Flushable * extra arguments are ignored. The number of arguments is * variable and may be zero. The maximum number of arguments is * limited by the maximum dimension of a Java array as defined by - * <cite>The Java™ Virtual Machine Specification</cite>. + * <cite>The Java Virtual Machine Specification</cite>. * The behaviour on a - * <tt>null</tt> argument depends on the <a + * {@code null} argument depends on the <a * href="../util/Formatter.html#syntax">conversion</a>. * * @throws IllegalFormatException @@ -176,8 +178,9 @@ public final class Console implements Flushable * A convenience method to write a formatted string to this console's * output stream using the specified format string and arguments. * - * <p> An invocation of this method of the form <tt>con.printf(format, - * args)</tt> behaves in exactly the same way as the invocation of + * <p> An invocation of this method of the form + * {@code con.printf(format, args)} behaves in exactly the same way + * as the invocation of * <pre>con.format(format, args)</pre>. * * @param format @@ -190,9 +193,9 @@ public final class Console implements Flushable * extra arguments are ignored. The number of arguments is * variable and may be zero. The maximum number of arguments is * limited by the maximum dimension of a Java array as defined by - * <cite>The Java™ Virtual Machine Specification</cite>. + * <cite>The Java Virtual Machine Specification</cite>. * The behaviour on a - * <tt>null</tt> argument depends on the <a + * {@code null} argument depends on the <a * href="../util/Formatter.html#syntax">conversion</a>. * * @throws IllegalFormatException @@ -223,7 +226,7 @@ public final class Console implements Flushable * string. If there are more arguments than format specifiers, the * extra arguments are ignored. The maximum number of arguments is * limited by the maximum dimension of a Java array as defined by - * <cite>The Java™ Virtual Machine Specification</cite>. + * <cite>The Java Virtual Machine Specification</cite>. * * @throws IllegalFormatException * If a format string contains an illegal syntax, a format @@ -238,14 +241,14 @@ public final class Console implements Flushable * If an I/O error occurs. * * @return A string containing the line read from the console, not - * including any line-termination characters, or <tt>null</tt> + * including any line-termination characters, or {@code null} * if an end of stream has been reached. */ public String readLine(String fmt, Object ... args) { String line = null; synchronized (writeLock) { synchronized(readLock) { - if (fmt.length() != 0) + if (!fmt.isEmpty()) pw.format(fmt, args); try { char[] ca = readline(false); @@ -266,7 +269,7 @@ public final class Console implements Flushable * If an I/O error occurs. * * @return A string containing the line read from the console, not - * including any line-termination characters, or <tt>null</tt> + * including any line-termination characters, or {@code null} * if an end of stream has been reached. */ public String readLine() { @@ -287,7 +290,7 @@ public final class Console implements Flushable * string. If there are more arguments than format specifiers, the * extra arguments are ignored. The maximum number of arguments is * limited by the maximum dimension of a Java array as defined by - * <cite>The Java™ Virtual Machine Specification</cite>. + * <cite>The Java Virtual Machine Specification</cite>. * * @throws IllegalFormatException * If a format string contains an illegal syntax, a format @@ -303,27 +306,30 @@ public final class Console implements Flushable * * @return A character array containing the password or passphrase read * from the console, not including any line-termination characters, - * or <tt>null</tt> if an end of stream has been reached. + * or {@code null} if an end of stream has been reached. */ public char[] readPassword(String fmt, Object ... args) { char[] passwd = null; synchronized (writeLock) { synchronized(readLock) { + // Android-removed: The hook is a no-op (but causes trouble when it's turned on). + // installShutdownHook(); try { - echoOff = echo(false); + restoreEcho = echo(false); } catch (IOException x) { throw new IOError(x); } IOError ioe = null; try { - if (fmt.length() != 0) + if (!fmt.isEmpty()) pw.format(fmt, args); passwd = readline(true); } catch (IOException x) { ioe = new IOError(x); } finally { try { - echoOff = echo(true); + if (restoreEcho) + restoreEcho = echo(true); } catch (IOException x) { if (ioe == null) ioe = new IOError(x); @@ -339,6 +345,35 @@ public final class Console implements Flushable return passwd; } + + // Android-removed: The hook is a no-op (but causes trouble when it's turned on). + /* + private void installShutdownHook() { + if (shutdownHookInstalled) + return; + try { + // Add a shutdown hook to restore console's echo state should + // it be necessary. + SharedSecrets.getJavaLangAccess() + .registerShutdownHook(0 /* shutdown hook invocation order *//*, + false /* only register if shutdown is not in progress *//*, + new Runnable() { + public void run() { + try { + if (restoreEcho) { + echo(true); + } + } catch (IOException x) { } + } + }); + } catch (IllegalStateException e) { + // shutdown is already in progress and readPassword is first used + // by a shutdown hook + } + shutdownHookInstalled = true; + } + */ + /** * Reads a password or passphrase from the console with echoing disabled * @@ -347,7 +382,7 @@ public final class Console implements Flushable * * @return A character array containing the password or passphrase read * from the console, not including any line-termination characters, - * or <tt>null</tt> if an end of stream has been reached. + * or {@code null} if an end of stream has been reached. */ public char[] readPassword() { return readPassword(""); @@ -361,17 +396,43 @@ public final class Console implements Flushable pw.flush(); } + + /** + * Returns the {@link java.nio.charset.Charset Charset} object used for + * the {@code Console}. + * <p> + * The returned charset corresponds to the input and output source + * (e.g., keyboard and/or display) specified by the host environment or user. + * It may not necessarily be the same as the default charset returned from + * {@link java.nio.charset.Charset#defaultCharset() Charset.defaultCharset()}. + * + * @return a {@link java.nio.charset.Charset Charset} object used for the + * {@code Console} + * @since 17 + */ + public Charset charset() { + assert CHARSET != null : "charset() should not return null"; + return CHARSET; + } + private Object readLock; private Object writeLock; private Reader reader; private Writer out; private PrintWriter pw; private Formatter formatter; - private Charset cs; private char[] rcb; + private boolean restoreEcho; + private boolean shutdownHookInstalled; private static native String encoding(); + /* + * Sets the console echo status to {@code on} and returns the previous + * console on/off status. + * @param on the echo status to set to. {@code true} for echo on and + * {@code false} for echo off + * @return true if the previous console echo status is on + */ private static native boolean echo(boolean on) throws IOException; - private static boolean echoOff; private char[] readline(boolean zeroOut) throws IOException { int len = reader.read(rcb, 0, rcb.length); @@ -514,8 +575,43 @@ public final class Console implements Flushable } } - // Android-removed: SharedSecrets setup and also the shutdown hook. - // The hook is a no-op (but causes trouble when it's turned on). + private static final Charset CHARSET; + static { + String csname = encoding(); + Charset cs = null; + // Android-changed: libcore doesn't traditionally support sun.stdout.encoding property. + /* + if (csname == null) { + csname = GetPropertyAction.privilegedGetProperty("sun.stdout.encoding"); + } + */ + if (csname != null) { + try { + cs = Charset.forName(csname); + } catch (Exception ignored) { + } + } + CHARSET = cs == null ? Charset.defaultCharset() : cs; + + // Set up JavaIOAccess in SharedSecrets + // Android-removed: SharedSecrets setup and also the shutdown hook. + /* + SharedSecrets.setJavaIOAccess(new JavaIOAccess() { + public Console console() { + if (istty()) { + if (cons == null) + cons = new Console(); + return cons; + } + return null; + } + + public Charset charset() { + return CHARSET; + } + }); + */ + } // Android-changed: Use @hide rather than sun.misc.SharedSecrets to expose console(). /** @hide */ @@ -528,7 +624,7 @@ public final class Console implements Flushable return null; } private static Console cons; - private native static boolean istty(); + private static native boolean istty(); private Console() { // BEGIN Android-changed: Support custom in/out streams for testing. this(new FileInputStream(FileDescriptor.in), new FileOutputStream(FileDescriptor.out)); @@ -539,24 +635,16 @@ public final class Console implements Flushable // END Android-changed: Support custom in/out streams for testing. readLock = new Object(); writeLock = new Object(); - String csname = encoding(); - if (csname != null) { - try { - cs = Charset.forName(csname); - } catch (Exception x) {} - } - if (cs == null) - cs = Charset.defaultCharset(); out = StreamEncoder.forOutputStreamWriter( outStream, writeLock, - cs); + CHARSET); pw = new PrintWriter(out, true) { public void close() {} }; formatter = new Formatter(out); reader = new LineReader(StreamDecoder.forInputStreamReader( inStream, readLock, - cs)); + CHARSET)); rcb = new char[1024]; } } |