aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Chang <vichang@google.com>2024-02-14 17:47:44 +0000
committerVictor Chang <vichang@google.com>2024-02-14 21:09:10 +0000
commitd09e3b41d2724730c4762462bd1d9ad1afa8efa6 (patch)
treea9f29f5c35e8b60b7520426af0bede84aa538390
parenta7c93248cfe462e9f0208133e9233a2b32101698 (diff)
parente0544eb85f5abcd99df02874f61e95f5d440a81d (diff)
downloadlibcore-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_UPSTREAM2
-rw-r--r--api/current.txt1
-rw-r--r--luni/src/test/java/libcore/java/io/ConsoleTest.java11
-rw-r--r--ojluni/annotations/flagged_api/java/io/Console.annotated.java56
-rw-r--r--ojluni/src/main/java/java/io/Console.java168
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&trade; 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&trade; 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&trade; 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&trade; 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];
}
}