/* * Copyright (C) 2014 The Android Open Source Project * Copyright (c) 1994, 2011, 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.lang; import dalvik.system.VMRuntime; import dalvik.system.VMStack; import android.system.StructPasswd; import android.system.StructUtsname; import android.system.ErrnoException; import java.io.*; import java.util.Locale; import java.util.Properties; import java.nio.channels.Channel; import java.nio.channels.spi.SelectorProvider; import libcore.icu.ICU; import libcore.io.Libcore; /** * The System class contains several useful class fields * and methods. It cannot be instantiated. * *

Among the facilities provided by the System class * are standard input, standard output, and error output streams; * access to externally defined properties and environment * variables; a means of loading files and libraries; and a utility * method for quickly copying a portion of an array. * * @author unascribed * @since JDK1.0 */ public final class System { /** Don't let anyone instantiate this class */ private System() { } /** * The "standard" input stream. This stream is already * open and ready to supply input data. Typically this stream * corresponds to keyboard input or another input source specified by * the host environment or user. */ public final static InputStream in; /** * The "standard" output stream. This stream is already * open and ready to accept output data. Typically this stream * corresponds to display output or another output destination * specified by the host environment or user. *

* For simple stand-alone Java applications, a typical way to write * a line of output data is: *

     *     System.out.println(data)
     * 
*

* See the println methods in class PrintStream. * * @see java.io.PrintStream#println() * @see java.io.PrintStream#println(boolean) * @see java.io.PrintStream#println(char) * @see java.io.PrintStream#println(char[]) * @see java.io.PrintStream#println(double) * @see java.io.PrintStream#println(float) * @see java.io.PrintStream#println(int) * @see java.io.PrintStream#println(long) * @see java.io.PrintStream#println(java.lang.Object) * @see java.io.PrintStream#println(java.lang.String) */ public final static PrintStream out; /** * The "standard" error output stream. This stream is already * open and ready to accept output data. *

* Typically this stream corresponds to display output or another * output destination specified by the host environment or user. By * convention, this output stream is used to display error messages * or other information that should come to the immediate attention * of a user even if the principal output stream, the value of the * variable out, has been redirected to a file or other * destination that is typically not continuously monitored. */ public final static PrintStream err; /** * Dedicated lock for GC / Finalization logic. */ private static final Object LOCK = new Object(); /** * Whether or not we need to do a GC before running the finalizers. */ private static boolean runGC; /** * If we just ran finalization, we might want to do a GC to free the finalized objects. * This lets us do gc/runFinlization/gc sequences but prevents back to back System.gc(). */ private static boolean justRanFinalization; /** * Reassigns the "standard" input stream. * *

First, if there is a security manager, its checkPermission * method is called with a RuntimePermission("setIO") permission * to see if it's ok to reassign the "standard" input stream. *

* * @param in the new standard input stream. * * @throws SecurityException * if a security manager exists and its * checkPermission method doesn't allow * reassigning of the standard input stream. * * @see SecurityManager#checkPermission * @see java.lang.RuntimePermission * * @since JDK1.1 */ public static void setIn(InputStream in) { setIn0(in); } /** * Reassigns the "standard" output stream. * *

First, if there is a security manager, its checkPermission * method is called with a RuntimePermission("setIO") permission * to see if it's ok to reassign the "standard" output stream. * * @param out the new standard output stream * * @throws SecurityException * if a security manager exists and its * checkPermission method doesn't allow * reassigning of the standard output stream. * * @see SecurityManager#checkPermission * @see java.lang.RuntimePermission * * @since JDK1.1 */ public static void setOut(PrintStream out) { setOut0(out); } /** * Reassigns the "standard" error output stream. * *

First, if there is a security manager, its checkPermission * method is called with a RuntimePermission("setIO") permission * to see if it's ok to reassign the "standard" error output stream. * * @param err the new standard error output stream. * * @throws SecurityException * if a security manager exists and its * checkPermission method doesn't allow * reassigning of the standard error output stream. * * @see SecurityManager#checkPermission * @see java.lang.RuntimePermission * * @since JDK1.1 */ public static void setErr(PrintStream err) { setErr0(err); } private static Console cons = null; /** * Returns the unique {@link java.io.Console Console} object associated * with the current Java virtual machine, if any. * * @return The system console, if any, otherwise null. * * @since 1.6 */ public static Console console() { synchronized (System.class) { if (cons == null) { cons = Console.console(); } return cons; } } /** * Returns the channel inherited from the entity that created this * Java virtual machine. * *

This method returns the channel obtained by invoking the * {@link java.nio.channels.spi.SelectorProvider#inheritedChannel * inheritedChannel} method of the system-wide default * {@link java.nio.channels.spi.SelectorProvider} object.

* *

In addition to the network-oriented channels described in * {@link java.nio.channels.spi.SelectorProvider#inheritedChannel * inheritedChannel}, this method may return other kinds of * channels in the future. * * @return The inherited channel, if any, otherwise null. * * @throws IOException * If an I/O error occurs * * @throws SecurityException * If a security manager is present and it does not * permit access to the channel. * * @since 1.5 */ public static Channel inheritedChannel() throws IOException { return SelectorProvider.provider().inheritedChannel(); } private static native void setIn0(InputStream in); private static native void setOut0(PrintStream out); private static native void setErr0(PrintStream err); /** * Throws {@code SecurityException} (except in case {@code sm == null}). * *

Security managers do not provide a secure environment for * executing untrusted code and are unsupported on Android. Untrusted code * cannot be safely isolated within a single VM on Android, so this method * always throws a {@code SecurityException} when passed a non-null SecurityManager * * @param sm a security manager * @throws SecurityException always, unless {@code sm == null} */ public static void setSecurityManager(SecurityManager sm) { if (sm != null) { throw new SecurityException(); } } /** * Always returns {@code null} in Android * * @return {@code null} in Android */ public static SecurityManager getSecurityManager() { // No-op on android. return null; } /** * Returns the current time in milliseconds. Note that * while the unit of time of the return value is a millisecond, * the granularity of the value depends on the underlying * operating system and may be larger. For example, many * operating systems measure time in units of tens of * milliseconds. * *

See the description of the class Date for * a discussion of slight discrepancies that may arise between * "computer time" and coordinated universal time (UTC). * * @return the difference, measured in milliseconds, between * the current time and midnight, January 1, 1970 UTC. * @see java.util.Date */ public static native long currentTimeMillis(); /** * Returns the current value of the running Java Virtual Machine's * high-resolution time source, in nanoseconds. * *

This method can only be used to measure elapsed time and is * not related to any other notion of system or wall-clock time. * The value returned represents nanoseconds since some fixed but * arbitrary origin time (perhaps in the future, so values * may be negative). The same origin is used by all invocations of * this method in an instance of a Java virtual machine; other * virtual machine instances are likely to use a different origin. * *

This method provides nanosecond precision, but not necessarily * nanosecond resolution (that is, how frequently the value changes) * - no guarantees are made except that the resolution is at least as * good as that of {@link #currentTimeMillis()}. * *

Differences in successive calls that span greater than * approximately 292 years (263 nanoseconds) will not * correctly compute elapsed time due to numerical overflow. * *

The values returned by this method become meaningful only when * the difference between two such values, obtained within the same * instance of a Java virtual machine, is computed. * *

For example, to measure how long some code takes to execute: *

 {@code
     * long startTime = System.nanoTime();
     * // ... the code being measured ...
     * long estimatedTime = System.nanoTime() - startTime;}
* *

To compare two nanoTime values *

 {@code
     * long t0 = System.nanoTime();
     * ...
     * long t1 = System.nanoTime();}
* * one should use {@code t1 - t0 < 0}, not {@code t1 < t0}, * because of the possibility of numerical overflow. * * @return the current value of the running Java Virtual Machine's * high-resolution time source, in nanoseconds * @since 1.5 */ public static native long nanoTime(); /** * Copies an array from the specified source array, beginning at the * specified position, to the specified position of the destination array. * A subsequence of array components are copied from the source * array referenced by src to the destination array * referenced by dest. The number of components copied is * equal to the length argument. The components at * positions srcPos through * srcPos+length-1 in the source array are copied into * positions destPos through * destPos+length-1, respectively, of the destination * array. *

* If the src and dest arguments refer to the * same array object, then the copying is performed as if the * components at positions srcPos through * srcPos+length-1 were first copied to a temporary * array with length components and then the contents of * the temporary array were copied into positions * destPos through destPos+length-1 of the * destination array. *

* If dest is null, then a * NullPointerException is thrown. *

* If src is null, then a * NullPointerException is thrown and the destination * array is not modified. *

* Otherwise, if any of the following is true, an * ArrayStoreException is thrown and the destination is * not modified: *

*

* Otherwise, if any of the following is true, an * IndexOutOfBoundsException is * thrown and the destination is not modified: *

*

* Otherwise, if any actual component of the source array from * position srcPos through * srcPos+length-1 cannot be converted to the component * type of the destination array by assignment conversion, an * ArrayStoreException is thrown. In this case, let * k be the smallest nonnegative integer less than * length such that src[srcPos+k] * cannot be converted to the component type of the destination * array; when the exception is thrown, source array components from * positions srcPos through * srcPos+k-1 * will already have been copied to destination array positions * destPos through * destPos+k-1 and no other * positions of the destination array will have been modified. * (Because of the restrictions already itemized, this * paragraph effectively applies only to the situation where both * arrays have component types that are reference types.) * * @param src the source array. * @param srcPos starting position in the source array. * @param dest the destination array. * @param destPos starting position in the destination data. * @param length the number of array elements to be copied. * @exception IndexOutOfBoundsException if copying would cause * access of data outside array bounds. * @exception ArrayStoreException if an element in the src * array could not be stored into the dest array * because of a type mismatch. * @exception NullPointerException if either src or * dest is null. */ public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length); // ----- BEGIN android ----- /** * The char array length threshold below which to use a Java * (non-native) version of arraycopy() instead of the native * version. See b/7103825. */ private static final int ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD = 32; /** * The char[] specialized version of arraycopy(). * * @hide internal use only */ public static void arraycopy(char[] src, int srcPos, char[] dst, int dstPos, int length) { if (src == null) { throw new NullPointerException("src == null"); } if (dst == null) { throw new NullPointerException("dst == null"); } if (srcPos < 0 || dstPos < 0 || length < 0 || srcPos > src.length - length || dstPos > dst.length - length) { throw new ArrayIndexOutOfBoundsException( "src.length=" + src.length + " srcPos=" + srcPos + " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length); } if (length <= ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD) { // Copy char by char for shorter arrays. if (src == dst && srcPos < dstPos && dstPos < srcPos + length) { // Copy backward (to avoid overwriting elements before // they are copied in case of an overlap on the same // array.) for (int i = length - 1; i >= 0; --i) { dst[dstPos + i] = src[srcPos + i]; } } else { // Copy forward. for (int i = 0; i < length; ++i) { dst[dstPos + i] = src[srcPos + i]; } } } else { // Call the native version for longer arrays. arraycopyCharUnchecked(src, srcPos, dst, dstPos, length); } } /** * The char[] specialized, unchecked, native version of * arraycopy(). This assumes error checking has been done. */ private static native void arraycopyCharUnchecked(char[] src, int srcPos, char[] dst, int dstPos, int length); /** * The byte array length threshold below which to use a Java * (non-native) version of arraycopy() instead of the native * version. See b/7103825. */ private static final int ARRAYCOPY_SHORT_BYTE_ARRAY_THRESHOLD = 32; /** * The byte[] specialized version of arraycopy(). * * @hide internal use only */ public static void arraycopy(byte[] src, int srcPos, byte[] dst, int dstPos, int length) { if (src == null) { throw new NullPointerException("src == null"); } if (dst == null) { throw new NullPointerException("dst == null"); } if (srcPos < 0 || dstPos < 0 || length < 0 || srcPos > src.length - length || dstPos > dst.length - length) { throw new ArrayIndexOutOfBoundsException( "src.length=" + src.length + " srcPos=" + srcPos + " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length); } if (length <= ARRAYCOPY_SHORT_BYTE_ARRAY_THRESHOLD) { // Copy byte by byte for shorter arrays. if (src == dst && srcPos < dstPos && dstPos < srcPos + length) { // Copy backward (to avoid overwriting elements before // they are copied in case of an overlap on the same // array.) for (int i = length - 1; i >= 0; --i) { dst[dstPos + i] = src[srcPos + i]; } } else { // Copy forward. for (int i = 0; i < length; ++i) { dst[dstPos + i] = src[srcPos + i]; } } } else { // Call the native version for longer arrays. arraycopyByteUnchecked(src, srcPos, dst, dstPos, length); } } /** * The byte[] specialized, unchecked, native version of * arraycopy(). This assumes error checking has been done. */ private static native void arraycopyByteUnchecked(byte[] src, int srcPos, byte[] dst, int dstPos, int length); /** * The short array length threshold below which to use a Java * (non-native) version of arraycopy() instead of the native * version. See b/7103825. */ private static final int ARRAYCOPY_SHORT_SHORT_ARRAY_THRESHOLD = 32; /** * The short[] specialized version of arraycopy(). * * @hide internal use only */ public static void arraycopy(short[] src, int srcPos, short[] dst, int dstPos, int length) { if (src == null) { throw new NullPointerException("src == null"); } if (dst == null) { throw new NullPointerException("dst == null"); } if (srcPos < 0 || dstPos < 0 || length < 0 || srcPos > src.length - length || dstPos > dst.length - length) { throw new ArrayIndexOutOfBoundsException( "src.length=" + src.length + " srcPos=" + srcPos + " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length); } if (length <= ARRAYCOPY_SHORT_SHORT_ARRAY_THRESHOLD) { // Copy short by short for shorter arrays. if (src == dst && srcPos < dstPos && dstPos < srcPos + length) { // Copy backward (to avoid overwriting elements before // they are copied in case of an overlap on the same // array.) for (int i = length - 1; i >= 0; --i) { dst[dstPos + i] = src[srcPos + i]; } } else { // Copy forward. for (int i = 0; i < length; ++i) { dst[dstPos + i] = src[srcPos + i]; } } } else { // Call the native version for longer arrays. arraycopyShortUnchecked(src, srcPos, dst, dstPos, length); } } /** * The short[] specialized, unchecked, native version of * arraycopy(). This assumes error checking has been done. */ private static native void arraycopyShortUnchecked(short[] src, int srcPos, short[] dst, int dstPos, int length); /** * The short array length threshold below which to use a Java * (non-native) version of arraycopy() instead of the native * version. See b/7103825. */ private static final int ARRAYCOPY_SHORT_INT_ARRAY_THRESHOLD = 32; /** * The int[] specialized version of arraycopy(). * * @hide internal use only */ public static void arraycopy(int[] src, int srcPos, int[] dst, int dstPos, int length) { if (src == null) { throw new NullPointerException("src == null"); } if (dst == null) { throw new NullPointerException("dst == null"); } if (srcPos < 0 || dstPos < 0 || length < 0 || srcPos > src.length - length || dstPos > dst.length - length) { throw new ArrayIndexOutOfBoundsException( "src.length=" + src.length + " srcPos=" + srcPos + " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length); } if (length <= ARRAYCOPY_SHORT_INT_ARRAY_THRESHOLD) { // Copy int by int for shorter arrays. if (src == dst && srcPos < dstPos && dstPos < srcPos + length) { // Copy backward (to avoid overwriting elements before // they are copied in case of an overlap on the same // array.) for (int i = length - 1; i >= 0; --i) { dst[dstPos + i] = src[srcPos + i]; } } else { // Copy forward. for (int i = 0; i < length; ++i) { dst[dstPos + i] = src[srcPos + i]; } } } else { // Call the native version for longer arrays. arraycopyIntUnchecked(src, srcPos, dst, dstPos, length); } } /** * The int[] specialized, unchecked, native version of * arraycopy(). This assumes error checking has been done. */ private static native void arraycopyIntUnchecked(int[] src, int srcPos, int[] dst, int dstPos, int length); /** * The short array length threshold below which to use a Java * (non-native) version of arraycopy() instead of the native * version. See b/7103825. */ private static final int ARRAYCOPY_SHORT_LONG_ARRAY_THRESHOLD = 32; /** * The long[] specialized version of arraycopy(). * * @hide internal use only */ public static void arraycopy(long[] src, int srcPos, long[] dst, int dstPos, int length) { if (src == null) { throw new NullPointerException("src == null"); } if (dst == null) { throw new NullPointerException("dst == null"); } if (srcPos < 0 || dstPos < 0 || length < 0 || srcPos > src.length - length || dstPos > dst.length - length) { throw new ArrayIndexOutOfBoundsException( "src.length=" + src.length + " srcPos=" + srcPos + " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length); } if (length <= ARRAYCOPY_SHORT_LONG_ARRAY_THRESHOLD) { // Copy long by long for shorter arrays. if (src == dst && srcPos < dstPos && dstPos < srcPos + length) { // Copy backward (to avoid overwriting elements before // they are copied in case of an overlap on the same // array.) for (int i = length - 1; i >= 0; --i) { dst[dstPos + i] = src[srcPos + i]; } } else { // Copy forward. for (int i = 0; i < length; ++i) { dst[dstPos + i] = src[srcPos + i]; } } } else { // Call the native version for longer arrays. arraycopyLongUnchecked(src, srcPos, dst, dstPos, length); } } /** * The long[] specialized, unchecked, native version of * arraycopy(). This assumes error checking has been done. */ private static native void arraycopyLongUnchecked(long[] src, int srcPos, long[] dst, int dstPos, int length); /** * The short array length threshold below which to use a Java * (non-native) version of arraycopy() instead of the native * version. See b/7103825. */ private static final int ARRAYCOPY_SHORT_FLOAT_ARRAY_THRESHOLD = 32; /** * The float[] specialized version of arraycopy(). * * @hide internal use only */ public static void arraycopy(float[] src, int srcPos, float[] dst, int dstPos, int length) { if (src == null) { throw new NullPointerException("src == null"); } if (dst == null) { throw new NullPointerException("dst == null"); } if (srcPos < 0 || dstPos < 0 || length < 0 || srcPos > src.length - length || dstPos > dst.length - length) { throw new ArrayIndexOutOfBoundsException( "src.length=" + src.length + " srcPos=" + srcPos + " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length); } if (length <= ARRAYCOPY_SHORT_FLOAT_ARRAY_THRESHOLD) { // Copy float by float for shorter arrays. if (src == dst && srcPos < dstPos && dstPos < srcPos + length) { // Copy backward (to avoid overwriting elements before // they are copied in case of an overlap on the same // array.) for (int i = length - 1; i >= 0; --i) { dst[dstPos + i] = src[srcPos + i]; } } else { // Copy forward. for (int i = 0; i < length; ++i) { dst[dstPos + i] = src[srcPos + i]; } } } else { // Call the native version for floater arrays. arraycopyFloatUnchecked(src, srcPos, dst, dstPos, length); } } /** * The float[] specialized, unchecked, native version of * arraycopy(). This assumes error checking has been done. */ private static native void arraycopyFloatUnchecked(float[] src, int srcPos, float[] dst, int dstPos, int length); /** * The short array length threshold below which to use a Java * (non-native) version of arraycopy() instead of the native * version. See b/7103825. */ private static final int ARRAYCOPY_SHORT_DOUBLE_ARRAY_THRESHOLD = 32; /** * The double[] specialized version of arraycopy(). * * @hide internal use only */ public static void arraycopy(double[] src, int srcPos, double[] dst, int dstPos, int length) { if (src == null) { throw new NullPointerException("src == null"); } if (dst == null) { throw new NullPointerException("dst == null"); } if (srcPos < 0 || dstPos < 0 || length < 0 || srcPos > src.length - length || dstPos > dst.length - length) { throw new ArrayIndexOutOfBoundsException( "src.length=" + src.length + " srcPos=" + srcPos + " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length); } if (length <= ARRAYCOPY_SHORT_DOUBLE_ARRAY_THRESHOLD) { // Copy double by double for shorter arrays. if (src == dst && srcPos < dstPos && dstPos < srcPos + length) { // Copy backward (to avoid overwriting elements before // they are copied in case of an overlap on the same // array.) for (int i = length - 1; i >= 0; --i) { dst[dstPos + i] = src[srcPos + i]; } } else { // Copy forward. for (int i = 0; i < length; ++i) { dst[dstPos + i] = src[srcPos + i]; } } } else { // Call the native version for floater arrays. arraycopyDoubleUnchecked(src, srcPos, dst, dstPos, length); } } /** * The double[] specialized, unchecked, native version of * arraycopy(). This assumes error checking has been done. */ private static native void arraycopyDoubleUnchecked(double[] src, int srcPos, double[] dst, int dstPos, int length); /** * The short array length threshold below which to use a Java * (non-native) version of arraycopy() instead of the native * version. See b/7103825. */ private static final int ARRAYCOPY_SHORT_BOOLEAN_ARRAY_THRESHOLD = 32; /** * The boolean[] specialized version of arraycopy(). * * @hide internal use only */ public static void arraycopy(boolean[] src, int srcPos, boolean[] dst, int dstPos, int length) { if (src == null) { throw new NullPointerException("src == null"); } if (dst == null) { throw new NullPointerException("dst == null"); } if (srcPos < 0 || dstPos < 0 || length < 0 || srcPos > src.length - length || dstPos > dst.length - length) { throw new ArrayIndexOutOfBoundsException( "src.length=" + src.length + " srcPos=" + srcPos + " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length); } if (length <= ARRAYCOPY_SHORT_BOOLEAN_ARRAY_THRESHOLD) { // Copy boolean by boolean for shorter arrays. if (src == dst && srcPos < dstPos && dstPos < srcPos + length) { // Copy backward (to avoid overwriting elements before // they are copied in case of an overlap on the same // array.) for (int i = length - 1; i >= 0; --i) { dst[dstPos + i] = src[srcPos + i]; } } else { // Copy forward. for (int i = 0; i < length; ++i) { dst[dstPos + i] = src[srcPos + i]; } } } else { // Call the native version for floater arrays. arraycopyBooleanUnchecked(src, srcPos, dst, dstPos, length); } } /** * The boolean[] specialized, unchecked, native version of * arraycopy(). This assumes error checking has been done. */ private static native void arraycopyBooleanUnchecked(boolean[] src, int srcPos, boolean[] dst, int dstPos, int length); // ----- END android ----- /** * Returns the same hash code for the given object as * would be returned by the default method hashCode(), * whether or not the given object's class overrides * hashCode(). * The hash code for the null reference is zero. * * @param x object for which the hashCode is to be calculated * @return the hashCode * @since JDK1.1 */ public static native int identityHashCode(Object x); /** * System properties. The following properties are guaranteed to be defined: *

*
java.version
Java version number *
java.vendor
Java vendor specific string *
java.vendor.url
Java vendor URL *
java.home
Java installation directory *
java.class.version
Java class version number *
java.class.path
Java classpath *
os.name
Operating System Name *
os.arch
Operating System Architecture *
os.version
Operating System Version *
file.separator
File separator ("/" on Unix) *
path.separator
Path separator (":" on Unix) *
line.separator
Line separator ("\n" on Unix) *
user.name
User account name *
user.home
User home directory *
user.dir
User's current working directory *
*/ private static Properties props; private static Properties unchangeableProps; private static native String[] specialProperties(); static final class PropertiesWithNonOverrideableDefaults extends Properties { PropertiesWithNonOverrideableDefaults(Properties defaults) { super(defaults); } @Override public Object put(Object key, Object value) { if (defaults.containsKey(key)) { logE("Ignoring attempt to set property \"" + key + "\" to value \"" + value + "\"."); return defaults.get(key); } return super.put(key, value); } @Override public Object remove(Object key) { if (defaults.containsKey(key)) { logE("Ignoring attempt to remove property \"" + key + "\"."); return null; } return super.remove(key); } } private static void parsePropertyAssignments(Properties p, String[] assignments) { for (String assignment : assignments) { int split = assignment.indexOf('='); String key = assignment.substring(0, split); String value = assignment.substring(split + 1); p.put(key, value); } } private static Properties initUnchangeableSystemProperties() { VMRuntime runtime = VMRuntime.getRuntime(); Properties p = new Properties(); // Set non-static properties. p.put("java.boot.class.path", runtime.bootClassPath()); p.put("java.class.path", runtime.classPath()); // TODO: does this make any sense? Should we just leave java.home unset? String javaHome = getenv("JAVA_HOME"); if (javaHome == null) { javaHome = "/system"; } p.put("java.home", javaHome); p.put("java.vm.version", runtime.vmVersion()); try { StructPasswd passwd = Libcore.os.getpwuid(Libcore.os.getuid()); p.put("user.name", passwd.pw_name); } catch (ErrnoException exception) { throw new AssertionError(exception); } StructUtsname info = Libcore.os.uname(); p.put("os.arch", info.machine); if (p.get("os.name") != null && !p.get("os.name").equals(info.sysname)) { logE("Wrong compile-time assumption for os.name: " + p.get("os.name") + " vs " + info.sysname); p.put("os.name", info.sysname); } p.put("os.version", info.release); // Undocumented Android-only properties. p.put("android.icu.library.version", ICU.getIcuVersion()); p.put("android.icu.unicode.version", ICU.getUnicodeVersion()); p.put("android.icu.cldr.version", ICU.getCldrVersion()); // Property override for ICU4J : this is the location of the ICU4C data. This // is prioritized over the properties in ICUConfig.properties. The issue with using // that is that it doesn't play well with jarjar and it needs complicated build rules // to change its default value. p.put("android.icu.impl.ICUBinary.dataPath", getenv("ANDROID_ROOT") + "/usr/icu"); parsePropertyAssignments(p, specialProperties()); // Override built-in properties with settings from the command line. // Note: it is not possible to override hardcoded values. parsePropertyAssignments(p, runtime.properties()); // Set static hardcoded properties. // These come last, as they must be guaranteed to agree with what a backend compiler // may assume when compiling the boot image on Android. for (String[] pair : AndroidHardcodedSystemProperties.STATIC_PROPERTIES) { if (p.containsKey(pair[0])) { logE("Ignoring command line argument: -D" + pair[0]); } if (pair[1] == null) { p.remove(pair[0]); } else { p.put(pair[0], pair[1]); } } return p; } private static Properties initProperties() { Properties p = new PropertiesWithNonOverrideableDefaults(unchangeableProps); setDefaultChangeableProperties(p); return p; } private static Properties setDefaultChangeableProperties(Properties p) { // On Android, each app gets its own temporary directory. // (See android.app.ActivityThread.) This is just a fallback default, // useful only on the host. // We check first if the property has not been set already: note that it // can only be set from the command line through the '-Djava.io.tmpdir=' option. if (!unchangeableProps.containsKey("java.io.tmpdir")) { p.put("java.io.tmpdir", "/tmp"); } // Android has always had an empty "user.home" (see docs for getProperty). // This is not useful for normal android apps which need to use android specific // APIs such as {@code Context.getFilesDir} and {@code Context.getCacheDir} but // we make it changeable for backward compatibility, so that they can change it // to a writeable location if required. // We check first if the property has not been set already: note that it // can only be set from the command line through the '-Duser.home=' option. if (!unchangeableProps.containsKey("user.home")) { p.put("user.home", ""); } return p; } /** * Inits an unchangeable system property with the given value. * * This is called from native code when the environment needs to change under native * bridge emulation. * * @hide also visible for tests. */ public static void setUnchangeableSystemProperty(String key, String value) { checkKey(key); unchangeableProps.put(key, value); } private static void addLegacyLocaleSystemProperties() { final String locale = getProperty("user.locale", ""); if (!locale.isEmpty()) { Locale l = Locale.forLanguageTag(locale); setUnchangeableSystemProperty("user.language", l.getLanguage()); setUnchangeableSystemProperty("user.region", l.getCountry()); setUnchangeableSystemProperty("user.variant", l.getVariant()); } else { // If "user.locale" isn't set we fall back to our old defaults of // language="en" and region="US" (if unset) and don't attempt to set it. // The Locale class will fall back to using user.language and // user.region if unset. final String language = getProperty("user.language", ""); final String region = getProperty("user.region", ""); if (language.isEmpty()) { setUnchangeableSystemProperty("user.language", "en"); } if (region.isEmpty()) { setUnchangeableSystemProperty("user.region", "US"); } } } /** * Determines the current system properties. * * *

The following properties are always provided by the Dalvik VM:

*

* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Name Meaning Example
file.separator {@link java.io.File#separator} {@code /}
java.class.path System class path {@code .}
java.class.version (Not useful on Android) {@code 50.0}
java.compiler (Not useful on Android) Empty
java.ext.dirs (Not useful on Android) Empty
java.home Location of the VM on the file system {@code /system}
java.io.tmpdir See {@link java.io.File#createTempFile} {@code /sdcard}
java.library.path Search path for JNI libraries {@code /vendor/lib:/system/lib}
java.vendor Human-readable VM vendor {@code The Android Project}
java.vendor.url URL for VM vendor's web site {@code http://www.android.com/}
java.version (Not useful on Android) {@code 0}
java.specification.version VM libraries version {@code 0.9}
java.specification.vendor VM libraries vendor {@code The Android Project}
java.specification.name VM libraries name {@code Dalvik Core Library}
java.vm.version VM implementation version {@code 1.2.0}
java.vm.vendor VM implementation vendor {@code The Android Project}
java.vm.name VM implementation name {@code Dalvik}
java.vm.specification.version VM specification version {@code 0.9}
java.vm.specification.vendor VM specification vendor {@code The Android Project}
java.vm.specification.name VM specification name {@code Dalvik Virtual Machine Specification}
line.separator The system line separator {@code \n}
os.arch OS architecture {@code armv7l}
os.name OS (kernel) name {@code Linux}
os.version OS (kernel) version {@code 2.6.32.9-g103d848}
path.separator See {@link java.io.File#pathSeparator} {@code :}
user.dir Base of non-absolute paths {@code /}
user.home (Not useful on Android) Empty
user.name (Not useful on Android) Empty
*

* Multiple paths in a system property value are separated by the path * separator character of the platform. * * @return the system properties * @see #setProperties * @see java.util.Properties */ public static Properties getProperties() { return props; } /** * Returns the system-dependent line separator string. It always * returns the same value - the initial value of the {@linkplain * #getProperty(String) system property} {@code line.separator}. * *

On UNIX systems, it returns {@code "\n"}; on Microsoft * Windows systems it returns {@code "\r\n"}. */ public static String lineSeparator() { return lineSeparator; } private static String lineSeparator; // Comment replaced with android one. /** * Attempts to set all system properties. Copies all properties from * {@code p} and discards system properties that are read only and cannot * be modified. See {@link #getProperty} for a list of such properties. */ public static void setProperties(Properties props) { Properties baseProperties = new PropertiesWithNonOverrideableDefaults(unchangeableProps); if (props != null) { baseProperties.putAll(props); } else { setDefaultChangeableProperties(baseProperties); } System.props = baseProperties; } /** * Gets the system property indicated by the specified key. * * If there is no current set of system properties, a set of system * properties is first created and initialized in the same manner as * for the getProperties method. * * @param key the name of the system property. * @return the string value of the system property, * or null if there is no property with that key. * * @exception NullPointerException if key is * null. * @exception IllegalArgumentException if key is empty. * @see #setProperty * @see java.lang.System#getProperties() */ public static String getProperty(String key) { checkKey(key); return props.getProperty(key); } /** * Gets the system property indicated by the specified key. *

* First, if there is a security manager, its * checkPropertyAccess method is called with the * key as its argument. *

* If there is no current set of system properties, a set of system * properties is first created and initialized in the same manner as * for the getProperties method. * * @param key the name of the system property. * @param def a default value. * @return the string value of the system property, * or the default value if there is no property with that key. * * @exception NullPointerException if key is * null. * @exception IllegalArgumentException if key is empty. * @see #setProperty * @see java.lang.System#getProperties() */ public static String getProperty(String key, String def) { checkKey(key); return props.getProperty(key, def); } /** * Sets the system property indicated by the specified key. * * @param key the name of the system property. * @param value the value of the system property. * @return the previous value of the system property, * or null if it did not have one. * * @exception NullPointerException if key or * value is null. * @exception IllegalArgumentException if key is empty. * @see #getProperty * @see java.lang.System#getProperty(java.lang.String) * @see java.lang.System#getProperty(java.lang.String, java.lang.String) * @since 1.2 */ public static String setProperty(String key, String value) { checkKey(key); return (String) props.setProperty(key, value); } /** * Removes the system property indicated by the specified key. * * @param key the name of the system property to be removed. * @return the previous string value of the system property, * or null if there was no property with that key. * * @exception NullPointerException if key is * null. * @exception IllegalArgumentException if key is empty. * @see #getProperty * @see #setProperty * @see java.util.Properties * @since 1.5 */ public static String clearProperty(String key) { checkKey(key); return (String) props.remove(key); } private static void checkKey(String key) { if (key == null) { throw new NullPointerException("key can't be null"); } if (key.equals("")) { throw new IllegalArgumentException("key can't be empty"); } } /** * Gets the value of the specified environment variable. An * environment variable is a system-dependent external named * value. * *

If a security manager exists, its * {@link SecurityManager#checkPermission checkPermission} * method is called with a * {@link RuntimePermission}("getenv."+name) * permission. This may result in a {@link SecurityException} * being thrown. If no exception is thrown the value of the * variable name is returned. * *

System * properties and environment variables are both * conceptually mappings between names and values. Both * mechanisms can be used to pass user-defined information to a * Java process. Environment variables have a more global effect, * because they are visible to all descendants of the process * which defines them, not just the immediate Java subprocess. * They can have subtly different semantics, such as case * insensitivity, on different operating systems. For these * reasons, environment variables are more likely to have * unintended side effects. It is best to use system properties * where possible. Environment variables should be used when a * global effect is desired, or when an external system interface * requires an environment variable (such as PATH). * *

On UNIX systems the alphabetic case of name is * typically significant, while on Microsoft Windows systems it is * typically not. For example, the expression * System.getenv("FOO").equals(System.getenv("foo")) * is likely to be true on Microsoft Windows. * * @param name the name of the environment variable * @return the string value of the variable, or null * if the variable is not defined in the system environment * @throws NullPointerException if name is null * @throws SecurityException * if a security manager exists and its * {@link SecurityManager#checkPermission checkPermission} * method doesn't allow access to the environment variable * name * @see #getenv() * @see ProcessBuilder#environment() */ public static String getenv(String name) { if (name == null) { throw new NullPointerException("name == null"); } return Libcore.os.getenv(name); } /** * Returns an unmodifiable string map view of the current system environment. * The environment is a system-dependent mapping from names to * values which is passed from parent to child processes. * *

If the system does not support environment variables, an * empty map is returned. * *

The returned map will never contain null keys or values. * Attempting to query the presence of a null key or value will * throw a {@link NullPointerException}. Attempting to query * the presence of a key or value which is not of type * {@link String} will throw a {@link ClassCastException}. * *

The returned map and its collection views may not obey the * general contract of the {@link Object#equals} and * {@link Object#hashCode} methods. * *

The returned map is typically case-sensitive on all platforms. * *

If a security manager exists, its * {@link SecurityManager#checkPermission checkPermission} * method is called with a * {@link RuntimePermission}("getenv.*") * permission. This may result in a {@link SecurityException} being * thrown. * *

When passing information to a Java subprocess, * system properties * are generally preferred over environment variables. * * @return the environment as a map of variable names to values * @throws SecurityException * if a security manager exists and its * {@link SecurityManager#checkPermission checkPermission} * method doesn't allow access to the process environment * @see #getenv(String) * @see ProcessBuilder#environment() * @since 1.5 */ public static java.util.Map getenv() { return ProcessEnvironment.getenv(); } /** * Terminates the currently running Java Virtual Machine. The * argument serves as a status code; by convention, a nonzero status * code indicates abnormal termination. *

* This method calls the exit method in class * Runtime. This method never returns normally. *

* The call System.exit(n) is effectively equivalent to * the call: *

     * Runtime.getRuntime().exit(n)
     * 
* * @param status exit status. * @throws SecurityException * if a security manager exists and its checkExit * method doesn't allow exit with the specified status. * @see java.lang.Runtime#exit(int) */ public static void exit(int status) { Runtime.getRuntime().exit(status); } /** * Runs the garbage collector. *

* Calling the gc method suggests that the Java Virtual * Machine expend effort toward recycling unused objects in order to * make the memory they currently occupy available for quick reuse. * When control returns from the method call, the Java Virtual * Machine has made a best effort to reclaim space from all discarded * objects. *

* The call System.gc() is effectively equivalent to the * call: *

     * Runtime.getRuntime().gc()
     * 
* * @see java.lang.Runtime#gc() */ public static void gc() { boolean shouldRunGC; synchronized (LOCK) { shouldRunGC = justRanFinalization; if (shouldRunGC) { justRanFinalization = false; } else { runGC = true; } } if (shouldRunGC) { Runtime.getRuntime().gc(); } } /** * Runs the finalization methods of any objects pending finalization. *

* Calling this method suggests that the Java Virtual Machine expend * effort toward running the finalize methods of objects * that have been found to be discarded but whose finalize * methods have not yet been run. When control returns from the * method call, the Java Virtual Machine has made a best effort to * complete all outstanding finalizations. *

* The call System.runFinalization() is effectively * equivalent to the call: *

     * Runtime.getRuntime().runFinalization()
     * 
* * @see java.lang.Runtime#runFinalization() */ public static void runFinalization() { boolean shouldRunGC; synchronized (LOCK) { shouldRunGC = runGC; runGC = false; } if (shouldRunGC) { Runtime.getRuntime().gc(); } Runtime.getRuntime().runFinalization(); synchronized (LOCK) { justRanFinalization = true; } } /** * Enable or disable finalization on exit; doing so specifies that the * finalizers of all objects that have finalizers that have not yet been * automatically invoked are to be run before the Java runtime exits. * By default, finalization on exit is disabled. * *

If there is a security manager, * its checkExit method is first called * with 0 as its argument to ensure the exit is allowed. * This could result in a SecurityException. * * @deprecated This method is inherently unsafe. It may result in * finalizers being called on live objects while other threads are * concurrently manipulating those objects, resulting in erratic * behavior or deadlock. * @param value indicating enabling or disabling of finalization * @throws SecurityException * if a security manager exists and its checkExit * method doesn't allow the exit. * * @see java.lang.Runtime#exit(int) * @see java.lang.Runtime#gc() * @see java.lang.SecurityManager#checkExit(int) * @since JDK1.1 */ @Deprecated public static void runFinalizersOnExit(boolean value) { Runtime.getRuntime().runFinalizersOnExit(value); } /** * Loads a code file with the specified filename from the local file * system as a dynamic library. The filename * argument must be a complete path name. *

* The call System.load(name) is effectively equivalent * to the call: *

     * Runtime.getRuntime().load(name)
     * 
* * @param filename the file to load. * @exception SecurityException if a security manager exists and its * checkLink method doesn't allow * loading of the specified dynamic library * @exception UnsatisfiedLinkError if the file does not exist. * @exception NullPointerException if filename is * null * @see java.lang.Runtime#load(java.lang.String) * @see java.lang.SecurityManager#checkLink(java.lang.String) */ public static void load(String filename) { Runtime.getRuntime().load0(VMStack.getStackClass1(), filename); } /** * Loads the system library specified by the libname * argument. The manner in which a library name is mapped to the * actual system library is system dependent. *

* The call System.loadLibrary(name) is effectively * equivalent to the call *

     * Runtime.getRuntime().loadLibrary(name)
     * 
* * @param libname the name of the library. * @exception SecurityException if a security manager exists and its * checkLink method doesn't allow * loading of the specified dynamic library * @exception UnsatisfiedLinkError if the library does not exist. * @exception NullPointerException if libname is * null * @see java.lang.Runtime#loadLibrary(java.lang.String) * @see java.lang.SecurityManager#checkLink(java.lang.String) */ public static void loadLibrary(String libname) { Runtime.getRuntime().loadLibrary0(VMStack.getCallingClassLoader(), libname); } /** * Maps a library name into a platform-specific string representing * a native library. * * @param libname the name of the library. * @return a platform-dependent native library name. * @exception NullPointerException if libname is * null * @see java.lang.System#loadLibrary(java.lang.String) * @see java.lang.ClassLoader#findLibrary(java.lang.String) * @since 1.2 */ public static native String mapLibraryName(String libname); /** * Initialize the system class. Called after thread initialization. */ static { unchangeableProps = initUnchangeableSystemProperties(); props = initProperties(); addLegacyLocaleSystemProperties(); sun.misc.Version.initSystemProperties(); // TODO: Confirm that this isn't something super important. // sun.misc.VM.saveAndRemoveProperties(props); lineSeparator = props.getProperty("line.separator"); FileInputStream fdIn = new FileInputStream(FileDescriptor.in); FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out); FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err); in = new BufferedInputStream(fdIn); out = new PrintStream(fdOut); err = new PrintStream(fdErr); // Initialize any miscellenous operating system settings that need to be // set for the class libraries. Currently this is no-op everywhere except // for Windows where the process-wide error mode is set before the java.io // classes are used. sun.misc.VM.initializeOSEnvironment(); // Subsystems that are invoked during initialization can invoke // sun.misc.VM.isBooted() in order to avoid doing things that should // wait until the application class loader has been set up. // IMPORTANT: Ensure that this remains the last initialization action! sun.misc.VM.booted(); } /** * @hide internal use only */ public static void logE(String message) { log('E', message, null); } /** * @hide internal use only */ public static void logE(String message, Throwable th) { log('E', message, th); } /** * @hide internal use only */ public static void logI(String message) { log('I', message, null); } /** * @hide internal use only */ public static void logI(String message, Throwable th) { log('I', message, th); } /** * @hide internal use only */ public static void logW(String message) { log('W', message, null); } /** * @hide internal use only */ public static void logW(String message, Throwable th) { log('W', message, th); } private static native void log(char type, String message, Throwable th); }