/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package java.lang; import android.system.ErrnoException; import android.system.StructPasswd; import android.system.StructUtsname; import dalvik.system.VMRuntime; import dalvik.system.VMStack; import java.io.BufferedInputStream; import java.io.Console; import java.io.FileDescriptor; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.InputStream; import java.io.IOException; import java.io.PrintStream; import java.nio.channels.Channel; import java.nio.channels.spi.SelectorProvider; import java.util.AbstractMap; import java.util.Collections; import java.util.HashMap; import java.util.Locale; import java.util.Map; import java.util.Properties; import java.util.Set; import libcore.icu.ICU; import libcore.io.Libcore; /** * Provides access to system-related information and resources including * standard input and output. Enables clients to dynamically load native * libraries. All methods of this class are accessed in a static way and the * class itself can not be instantiated. * * @see Runtime */ public final class System { /** * Default input stream. */ public static final InputStream in; /** * Default output stream. */ public static final PrintStream out; /** * Default error output stream. */ public static final PrintStream err; private static final String PATH_SEPARATOR = ":"; private static final String LINE_SEPARATOR = "\n"; private static final String FILE_SEPARATOR = "/"; private static final Properties unchangeableSystemProperties; private static Properties systemProperties; /** * 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; static { err = new PrintStream(new FileOutputStream(FileDescriptor.err)); out = new PrintStream(new FileOutputStream(FileDescriptor.out)); in = new BufferedInputStream(new FileInputStream(FileDescriptor.in)); unchangeableSystemProperties = initUnchangeableSystemProperties(); systemProperties = createSystemProperties(); addLegacyLocaleSystemProperties(); } 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"); } } } /** * Sets the standard input stream to the given user defined input stream. * * @param newIn * the user defined input stream to set as the standard input * stream. */ public static void setIn(InputStream newIn) { setFieldImpl("in", "Ljava/io/InputStream;", newIn); } /** * Sets the standard output stream to the given user defined output stream. * * @param newOut * the user defined output stream to set as the standard output * stream. */ public static void setOut(PrintStream newOut) { setFieldImpl("out", "Ljava/io/PrintStream;", newOut); } /** * Sets the standard error output stream to the given user defined output * stream. * * @param newErr * the user defined output stream to set as the standard error * output stream. */ public static void setErr(PrintStream newErr) { setFieldImpl("err", "Ljava/io/PrintStream;", newErr); } /** * Prevents this class from being instantiated. */ private System() { } /** * Copies {@code length} elements from the array {@code src}, * starting at offset {@code srcPos}, into the array {@code dst}, * starting at offset {@code dstPos}. * *
The source and destination arrays can be the same array, * in which case copying is performed as if the source elements * are first copied into a temporary array and then into the * destination array. * * @param src * the source array to copy the content. * @param srcPos * the starting index of the content in {@code src}. * @param dst * the destination array to copy the data into. * @param dstPos * the starting index for the copied content in {@code dst}. * @param length * the number of elements to be copied. */ public static native void arraycopy(Object src, int srcPos, Object dst, int dstPos, int length); /** * 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); /** * Returns the current time in milliseconds since January 1, 1970 00:00:00.0 UTC. * *
This method always returns UTC times, regardless of the system's time zone. * This is often called "Unix time" or "epoch time". * Use a {@link java.text.DateFormat} instance to format this time for display to a human. * *
This method shouldn't be used for measuring timeouts or * other elapsed time measurements, as changing the system time can affect * the results. Use {@link #nanoTime} for that. */ public static native long currentTimeMillis(); /** * Returns the current timestamp of the most precise timer available on the * local system, in nanoseconds. Equivalent to Linux's {@code CLOCK_MONOTONIC}. * *
This timestamp should only be used to measure a duration by comparing it
* against another timestamp on the same device.
* Values returned by this method do not have a defined correspondence to
* wall clock times; the zero value is typically whenever the device last booted.
* Use {@link #currentTimeMillis} if you want to know what time it is.
*/
public static native long nanoTime();
/**
* Causes the VM to stop running and the program to exit with the given exit status.
* If {@link #runFinalizersOnExit(boolean)} has been previously invoked with a
* {@code true} argument, then all objects will be properly
* garbage-collected and finalized first.
*/
public static void exit(int code) {
Runtime.getRuntime().exit(code);
}
/**
* Indicates to the VM that it would be a good time to run the
* garbage collector. Note that this is a hint only. There is no guarantee
* that the garbage collector will actually be run.
*/
public static void gc() {
boolean shouldRunGC;
synchronized(lock) {
shouldRunGC = justRanFinalization;
if (shouldRunGC) {
justRanFinalization = false;
} else {
runGC = true;
}
}
if (shouldRunGC) {
Runtime.getRuntime().gc();
}
}
/**
* Returns the value of the environment variable with the given name, or null if no such
* variable exists.
*/
public static String getenv(String name) {
if (name == null) {
throw new NullPointerException("name == null");
}
return Libcore.os.getenv(name);
}
/**
* Returns an unmodifiable map of all environment variables to their values.
*/
public static Map The following properties are always provided by the Dalvik VM: All of the above properties except for {@code user.home} and {@code java.io.tmpdir}
* cannot be modified. Any attempt to change them will be a no-op.
*
* @param propertyName
* the name of the system property to look up.
* @return the value of the specified system property or {@code null} if the
* property doesn't exist.
*/
public static String getProperty(String propertyName) {
return getProperty(propertyName, null);
}
/**
* Returns the value of a particular system property. The {@code
* defaultValue} will be returned if no such property has been found.
*/
public static String getProperty(String name, String defaultValue) {
checkPropertyName(name);
return systemProperties.getProperty(name, defaultValue);
}
/**
* Sets the value of a particular system property. Most system properties
* are read only and cannot be cleared or modified. See {@link #getProperty} for a
* list of such properties.
*
* @return the old value of the property or {@code null} if the property
* didn't exist.
*/
public static String setProperty(String name, String value) {
checkPropertyName(name);
return (String) systemProperties.setProperty(name, value);
}
/**
* Removes a specific system property. Most system properties
* are read only and cannot be cleared or modified. See {@link #getProperty} for a
* list of such properties.
*
* @return the property value or {@code null} if the property didn't exist.
* @throws NullPointerException
* if the argument is {@code null}.
* @throws IllegalArgumentException
* if the argument is empty.
*/
public static String clearProperty(String name) {
checkPropertyName(name);
return (String) systemProperties.remove(name);
}
private static void checkPropertyName(String name) {
if (name == null) {
throw new NullPointerException("name == null");
}
if (name.isEmpty()) {
throw new IllegalArgumentException("name is empty");
}
}
/**
* Returns the {@link java.io.Console} associated with this VM, or null.
* Not all VMs will have an associated console. A console is typically only
* available for programs run from the command line.
* @since 1.6
*/
public static Console console() {
return Console.getConsole();
}
/**
* Returns null. Android does not use {@code SecurityManager}. This method
* is only provided for source compatibility.
*
* @return null
*/
public static SecurityManager getSecurityManager() {
return null;
}
/**
* Returns an integer hash code for the parameter. The hash code returned is
* the same one that would be returned by the method {@code
* java.lang.Object.hashCode()}, whether or not the object's class has
* overridden hashCode(). The hash code for {@code null} is {@code 0}.
*
* @param anObject
* the object to calculate the hash code.
* @return the hash code for the given object.
* @see java.lang.Object#hashCode
*/
public static native int identityHashCode(Object anObject);
/**
* Returns the system's line separator. On Android, this is {@code "\n"}. The value comes from
* the value of the {@code line.separator} system property.
*
* On Android versions before Lollipop the {@code line.separator} system property can be
* modified but this method continues to return the original value. The system property cannot
* be modified on later versions of Android.
*
* @since 1.7
*/
public static String lineSeparator() {
return LINE_SEPARATOR;
}
/**
* See {@link Runtime#load}.
*/
public static void load(String pathName) {
Runtime.getRuntime().load(pathName, VMStack.getCallingClassLoader());
}
/**
* See {@link Runtime#loadLibrary}.
*/
public static void loadLibrary(String libName) {
Runtime.getRuntime().loadLibrary(libName, VMStack.getCallingClassLoader());
}
/**
* @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);
/**
* Provides a hint to the VM that it would be useful to attempt
* to perform any outstanding object finalization.
*/
public static void runFinalization() {
boolean shouldRunGC;
synchronized(lock) {
shouldRunGC = runGC;
runGC = false;
}
if (shouldRunGC) {
Runtime.getRuntime().gc();
}
Runtime.getRuntime().runFinalization();
synchronized(lock) {
justRanFinalization = true;
}
}
/**
* Ensures that, when the VM is about to exit, all objects are
* finalized. Note that all finalization which occurs when the system is
* exiting is performed after all running threads have been terminated.
*
* @param flag
* the flag determines if finalization on exit is enabled.
* @deprecated This method is unsafe.
*/
@SuppressWarnings("deprecation")
@Deprecated
public static void runFinalizersOnExit(boolean flag) {
Runtime.runFinalizersOnExit(flag);
}
/**
* 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 p) {
PropertiesWithNonOverrideableDefaults userProperties =
new PropertiesWithNonOverrideableDefaults(unchangeableSystemProperties);
if (p != null) {
userProperties.putAll(p);
} else {
// setProperties(null) is documented to restore defaults.
setDefaultChangeableProperties(userProperties);
}
systemProperties = userProperties;
}
/**
* Throws {@code SecurityException}.
*
* 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}.
*
* @param sm a security manager
* @throws SecurityException always
*/
public static void setSecurityManager(SecurityManager sm) {
if (sm != null) {
throw new SecurityException();
}
}
/**
* Returns the platform specific file name format for the shared library
* named by the argument. On Android, this would turn {@code "MyLibrary"} into
* {@code "libMyLibrary.so"}.
*/
public static String mapLibraryName(String nickname) {
if (nickname == null) {
throw new NullPointerException("nickname == null");
}
return "lib" + nickname + ".so";
}
/**
* Used to set System.err, System.in, and System.out.
*/
private static native void setFieldImpl(String field, String signature, Object stream);
/**
* A properties class that prohibits changes to any of the properties
* contained in its defaults.
*/
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);
}
}
/**
* The unmodifiable environment variables map. System.getenv() specifies
* that this map must throw when passed non-String keys.
*/
static class SystemEnvironment extends AbstractMap
*
*
*
*
* 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