Home | History | Annotate | Download | only in lang
      1 /*
      2  * Licensed to the Apache Software Foundation (ASF) under one or more
      3  * contributor license agreements.  See the NOTICE file distributed with
      4  * this work for additional information regarding copyright ownership.
      5  * The ASF licenses this file to You under the Apache License, Version 2.0
      6  * (the "License"); you may not use this file except in compliance with
      7  * the License.  You may obtain a copy of the License at
      8  *
      9  *     http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 /*
     18  * Copyright (C) 2008 The Android Open Source Project
     19  *
     20  * Licensed under the Apache License, Version 2.0 (the "License");
     21  * you may not use this file except in compliance with the License.
     22  * You may obtain a copy of the License at
     23  *
     24  *      http://www.apache.org/licenses/LICENSE-2.0
     25  *
     26  * Unless required by applicable law or agreed to in writing, software
     27  * distributed under the License is distributed on an "AS IS" BASIS,
     28  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     29  * See the License for the specific language governing permissions and
     30  * limitations under the License.
     31  */
     32 
     33 package java.lang;
     34 
     35 import android.system.ErrnoException;
     36 import android.system.StructPasswd;
     37 import android.system.StructUtsname;
     38 import dalvik.system.VMRuntime;
     39 import dalvik.system.VMStack;
     40 import java.io.BufferedInputStream;
     41 import java.io.Console;
     42 import java.io.FileDescriptor;
     43 import java.io.FileInputStream;
     44 import java.io.FileOutputStream;
     45 import java.io.InputStream;
     46 import java.io.IOException;
     47 import java.io.PrintStream;
     48 import java.nio.channels.Channel;
     49 import java.nio.channels.spi.SelectorProvider;
     50 import java.util.AbstractMap;
     51 import java.util.Collections;
     52 import java.util.HashMap;
     53 import java.util.Map;
     54 import java.util.Properties;
     55 import java.util.Set;
     56 import libcore.icu.ICU;
     57 import libcore.io.Libcore;
     58 
     59 /**
     60  * Provides access to system-related information and resources including
     61  * standard input and output. Enables clients to dynamically load native
     62  * libraries. All methods of this class are accessed in a static way and the
     63  * class itself can not be instantiated.
     64  *
     65  * @see Runtime
     66  */
     67 public final class System {
     68 
     69     /**
     70      * Default input stream.
     71      */
     72     public static final InputStream in;
     73 
     74     /**
     75      * Default output stream.
     76      */
     77     public static final PrintStream out;
     78 
     79     /**
     80      * Default error output stream.
     81      */
     82     public static final PrintStream err;
     83 
     84     private static final String lineSeparator;
     85     private static final Properties unchangeableSystemProperties;
     86     private static Properties systemProperties;
     87 
     88     /**
     89      * Dedicated lock for GC / Finalization logic.
     90      */
     91     private static final Object lock = new Object();
     92 
     93     /**
     94      * Whether or not we need to do a GC before running the finalizers.
     95      */
     96     private static boolean runGC;
     97 
     98     /**
     99      * If we just ran finalization, we might want to do a GC to free the finalized objects.
    100      * This lets us do gc/runFinlization/gc sequences but prevents back to back System.gc().
    101      */
    102     private static boolean justRanFinalization;
    103 
    104     static {
    105         err = new PrintStream(new FileOutputStream(FileDescriptor.err));
    106         out = new PrintStream(new FileOutputStream(FileDescriptor.out));
    107         in = new BufferedInputStream(new FileInputStream(FileDescriptor.in));
    108         unchangeableSystemProperties = initUnchangeableSystemProperties();
    109         systemProperties = createSystemProperties();
    110         lineSeparator = System.getProperty("line.separator");
    111     }
    112 
    113     /**
    114      * Sets the standard input stream to the given user defined input stream.
    115      *
    116      * @param newIn
    117      *            the user defined input stream to set as the standard input
    118      *            stream.
    119      */
    120     public static void setIn(InputStream newIn) {
    121         setFieldImpl("in", "Ljava/io/InputStream;", newIn);
    122     }
    123 
    124     /**
    125      * Sets the standard output stream to the given user defined output stream.
    126      *
    127      * @param newOut
    128      *            the user defined output stream to set as the standard output
    129      *            stream.
    130      */
    131     public static void setOut(PrintStream newOut) {
    132         setFieldImpl("out", "Ljava/io/PrintStream;", newOut);
    133     }
    134 
    135     /**
    136      * Sets the standard error output stream to the given user defined output
    137      * stream.
    138      *
    139      * @param newErr
    140      *            the user defined output stream to set as the standard error
    141      *            output stream.
    142      */
    143     public static void setErr(PrintStream newErr) {
    144         setFieldImpl("err", "Ljava/io/PrintStream;", newErr);
    145     }
    146 
    147     /**
    148      * Prevents this class from being instantiated.
    149      */
    150     private System() {
    151     }
    152 
    153     /**
    154      * Copies {@code length} elements from the array {@code src},
    155      * starting at offset {@code srcPos}, into the array {@code dst},
    156      * starting at offset {@code dstPos}.
    157      *
    158      * <p>The source and destination arrays can be the same array,
    159      * in which case copying is performed as if the source elements
    160      * are first copied into a temporary array and then into the
    161      * destination array.
    162      *
    163      * @param src
    164      *            the source array to copy the content.
    165      * @param srcPos
    166      *            the starting index of the content in {@code src}.
    167      * @param dst
    168      *            the destination array to copy the data into.
    169      * @param dstPos
    170      *            the starting index for the copied content in {@code dst}.
    171      * @param length
    172      *            the number of elements to be copied.
    173      */
    174 
    175     public static native void arraycopy(Object src, int srcPos,
    176         Object dst, int dstPos, int length);
    177 
    178     /**
    179      * The char array length threshold below which to use a Java
    180      * (non-native) version of arraycopy() instead of the native
    181      * version. See b/7103825.
    182      */
    183     private static final int ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD = 32;
    184 
    185     /**
    186      * The char[] specialized version of arraycopy().
    187      *
    188      * @hide internal use only
    189      */
    190     public static void arraycopy(char[] src, int srcPos, char[] dst, int dstPos, int length) {
    191         if (src == null) {
    192             throw new NullPointerException("src == null");
    193         }
    194         if (dst == null) {
    195             throw new NullPointerException("dst == null");
    196         }
    197         if (srcPos < 0 || dstPos < 0 || length < 0 ||
    198             srcPos > src.length - length || dstPos > dst.length - length) {
    199             throw new ArrayIndexOutOfBoundsException(
    200                 "src.length=" + src.length + " srcPos=" + srcPos +
    201                 " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
    202         }
    203         if (length <= ARRAYCOPY_SHORT_CHAR_ARRAY_THRESHOLD) {
    204             // Copy char by char for shorter arrays.
    205             if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
    206                 // Copy backward (to avoid overwriting elements before
    207                 // they are copied in case of an overlap on the same
    208                 // array.)
    209                 for (int i = length - 1; i >= 0; --i) {
    210                     dst[dstPos + i] = src[srcPos + i];
    211                 }
    212             } else {
    213                 // Copy forward.
    214                 for (int i = 0; i < length; ++i) {
    215                     dst[dstPos + i] = src[srcPos + i];
    216                 }
    217             }
    218         } else {
    219             // Call the native version for longer arrays.
    220             arraycopyCharUnchecked(src, srcPos, dst, dstPos, length);
    221         }
    222     }
    223 
    224     /**
    225      * The char[] specialized, unchecked, native version of
    226      * arraycopy(). This assumes error checking has been done.
    227      */
    228     private static native void arraycopyCharUnchecked(char[] src, int srcPos,
    229         char[] dst, int dstPos, int length);
    230 
    231     /**
    232      * The byte array length threshold below which to use a Java
    233      * (non-native) version of arraycopy() instead of the native
    234      * version. See b/7103825.
    235      */
    236     private static final int ARRAYCOPY_SHORT_BYTE_ARRAY_THRESHOLD = 32;
    237 
    238     /**
    239      * The byte[] specialized version of arraycopy().
    240      *
    241      * @hide internal use only
    242      */
    243     public static void arraycopy(byte[] src, int srcPos, byte[] dst, int dstPos, int length) {
    244         if (src == null) {
    245             throw new NullPointerException("src == null");
    246         }
    247         if (dst == null) {
    248             throw new NullPointerException("dst == null");
    249         }
    250         if (srcPos < 0 || dstPos < 0 || length < 0 ||
    251             srcPos > src.length - length || dstPos > dst.length - length) {
    252             throw new ArrayIndexOutOfBoundsException(
    253                 "src.length=" + src.length + " srcPos=" + srcPos +
    254                 " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
    255         }
    256         if (length <= ARRAYCOPY_SHORT_BYTE_ARRAY_THRESHOLD) {
    257             // Copy byte by byte for shorter arrays.
    258             if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
    259                 // Copy backward (to avoid overwriting elements before
    260                 // they are copied in case of an overlap on the same
    261                 // array.)
    262                 for (int i = length - 1; i >= 0; --i) {
    263                     dst[dstPos + i] = src[srcPos + i];
    264                 }
    265             } else {
    266                 // Copy forward.
    267                 for (int i = 0; i < length; ++i) {
    268                     dst[dstPos + i] = src[srcPos + i];
    269                 }
    270             }
    271         } else {
    272             // Call the native version for longer arrays.
    273             arraycopyByteUnchecked(src, srcPos, dst, dstPos, length);
    274         }
    275     }
    276 
    277     /**
    278      * The byte[] specialized, unchecked, native version of
    279      * arraycopy(). This assumes error checking has been done.
    280      */
    281     private static native void arraycopyByteUnchecked(byte[] src, int srcPos,
    282         byte[] dst, int dstPos, int length);
    283 
    284     /**
    285      * The short array length threshold below which to use a Java
    286      * (non-native) version of arraycopy() instead of the native
    287      * version. See b/7103825.
    288      */
    289     private static final int ARRAYCOPY_SHORT_SHORT_ARRAY_THRESHOLD = 32;
    290 
    291     /**
    292      * The short[] specialized version of arraycopy().
    293      *
    294      * @hide internal use only
    295      */
    296     public static void arraycopy(short[] src, int srcPos, short[] dst, int dstPos, int length) {
    297         if (src == null) {
    298             throw new NullPointerException("src == null");
    299         }
    300         if (dst == null) {
    301             throw new NullPointerException("dst == null");
    302         }
    303         if (srcPos < 0 || dstPos < 0 || length < 0 ||
    304             srcPos > src.length - length || dstPos > dst.length - length) {
    305             throw new ArrayIndexOutOfBoundsException(
    306                 "src.length=" + src.length + " srcPos=" + srcPos +
    307                 " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
    308         }
    309         if (length <= ARRAYCOPY_SHORT_SHORT_ARRAY_THRESHOLD) {
    310             // Copy short by short for shorter arrays.
    311             if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
    312                 // Copy backward (to avoid overwriting elements before
    313                 // they are copied in case of an overlap on the same
    314                 // array.)
    315                 for (int i = length - 1; i >= 0; --i) {
    316                     dst[dstPos + i] = src[srcPos + i];
    317                 }
    318             } else {
    319                 // Copy forward.
    320                 for (int i = 0; i < length; ++i) {
    321                     dst[dstPos + i] = src[srcPos + i];
    322                 }
    323             }
    324         } else {
    325             // Call the native version for longer arrays.
    326             arraycopyShortUnchecked(src, srcPos, dst, dstPos, length);
    327         }
    328     }
    329 
    330     /**
    331      * The short[] specialized, unchecked, native version of
    332      * arraycopy(). This assumes error checking has been done.
    333      */
    334     private static native void arraycopyShortUnchecked(short[] src, int srcPos,
    335         short[] dst, int dstPos, int length);
    336 
    337     /**
    338      * The short array length threshold below which to use a Java
    339      * (non-native) version of arraycopy() instead of the native
    340      * version. See b/7103825.
    341      */
    342     private static final int ARRAYCOPY_SHORT_INT_ARRAY_THRESHOLD = 32;
    343 
    344     /**
    345      * The int[] specialized version of arraycopy().
    346      *
    347      * @hide internal use only
    348      */
    349     public static void arraycopy(int[] src, int srcPos, int[] dst, int dstPos, int length) {
    350         if (src == null) {
    351             throw new NullPointerException("src == null");
    352         }
    353         if (dst == null) {
    354             throw new NullPointerException("dst == null");
    355         }
    356         if (srcPos < 0 || dstPos < 0 || length < 0 ||
    357             srcPos > src.length - length || dstPos > dst.length - length) {
    358             throw new ArrayIndexOutOfBoundsException(
    359                 "src.length=" + src.length + " srcPos=" + srcPos +
    360                 " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
    361         }
    362         if (length <= ARRAYCOPY_SHORT_INT_ARRAY_THRESHOLD) {
    363             // Copy int by int for shorter arrays.
    364             if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
    365                 // Copy backward (to avoid overwriting elements before
    366                 // they are copied in case of an overlap on the same
    367                 // array.)
    368                 for (int i = length - 1; i >= 0; --i) {
    369                     dst[dstPos + i] = src[srcPos + i];
    370                 }
    371             } else {
    372                 // Copy forward.
    373                 for (int i = 0; i < length; ++i) {
    374                     dst[dstPos + i] = src[srcPos + i];
    375                 }
    376             }
    377         } else {
    378             // Call the native version for longer arrays.
    379             arraycopyIntUnchecked(src, srcPos, dst, dstPos, length);
    380         }
    381     }
    382 
    383     /**
    384      * The int[] specialized, unchecked, native version of
    385      * arraycopy(). This assumes error checking has been done.
    386      */
    387     private static native void arraycopyIntUnchecked(int[] src, int srcPos,
    388         int[] dst, int dstPos, int length);
    389 
    390     /**
    391      * The short array length threshold below which to use a Java
    392      * (non-native) version of arraycopy() instead of the native
    393      * version. See b/7103825.
    394      */
    395     private static final int ARRAYCOPY_SHORT_LONG_ARRAY_THRESHOLD = 32;
    396 
    397     /**
    398      * The long[] specialized version of arraycopy().
    399      *
    400      * @hide internal use only
    401      */
    402     public static void arraycopy(long[] src, int srcPos, long[] dst, int dstPos, int length) {
    403         if (src == null) {
    404             throw new NullPointerException("src == null");
    405         }
    406         if (dst == null) {
    407             throw new NullPointerException("dst == null");
    408         }
    409         if (srcPos < 0 || dstPos < 0 || length < 0 ||
    410             srcPos > src.length - length || dstPos > dst.length - length) {
    411             throw new ArrayIndexOutOfBoundsException(
    412                 "src.length=" + src.length + " srcPos=" + srcPos +
    413                 " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
    414         }
    415         if (length <= ARRAYCOPY_SHORT_LONG_ARRAY_THRESHOLD) {
    416             // Copy long by long for shorter arrays.
    417             if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
    418                 // Copy backward (to avoid overwriting elements before
    419                 // they are copied in case of an overlap on the same
    420                 // array.)
    421                 for (int i = length - 1; i >= 0; --i) {
    422                     dst[dstPos + i] = src[srcPos + i];
    423                 }
    424             } else {
    425                 // Copy forward.
    426                 for (int i = 0; i < length; ++i) {
    427                     dst[dstPos + i] = src[srcPos + i];
    428                 }
    429             }
    430         } else {
    431             // Call the native version for longer arrays.
    432             arraycopyLongUnchecked(src, srcPos, dst, dstPos, length);
    433         }
    434     }
    435 
    436     /**
    437      * The long[] specialized, unchecked, native version of
    438      * arraycopy(). This assumes error checking has been done.
    439      */
    440     private static native void arraycopyLongUnchecked(long[] src, int srcPos,
    441         long[] dst, int dstPos, int length);
    442 
    443     /**
    444      * The short array length threshold below which to use a Java
    445      * (non-native) version of arraycopy() instead of the native
    446      * version. See b/7103825.
    447      */
    448     private static final int ARRAYCOPY_SHORT_FLOAT_ARRAY_THRESHOLD = 32;
    449 
    450     /**
    451      * The float[] specialized version of arraycopy().
    452      *
    453      * @hide internal use only
    454      */
    455     public static void arraycopy(float[] src, int srcPos, float[] dst, int dstPos, int length) {
    456         if (src == null) {
    457             throw new NullPointerException("src == null");
    458         }
    459         if (dst == null) {
    460             throw new NullPointerException("dst == null");
    461         }
    462         if (srcPos < 0 || dstPos < 0 || length < 0 ||
    463             srcPos > src.length - length || dstPos > dst.length - length) {
    464             throw new ArrayIndexOutOfBoundsException(
    465                 "src.length=" + src.length + " srcPos=" + srcPos +
    466                 " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
    467         }
    468         if (length <= ARRAYCOPY_SHORT_FLOAT_ARRAY_THRESHOLD) {
    469             // Copy float by float for shorter arrays.
    470             if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
    471                 // Copy backward (to avoid overwriting elements before
    472                 // they are copied in case of an overlap on the same
    473                 // array.)
    474                 for (int i = length - 1; i >= 0; --i) {
    475                     dst[dstPos + i] = src[srcPos + i];
    476                 }
    477             } else {
    478                 // Copy forward.
    479                 for (int i = 0; i < length; ++i) {
    480                     dst[dstPos + i] = src[srcPos + i];
    481                 }
    482             }
    483         } else {
    484             // Call the native version for floater arrays.
    485             arraycopyFloatUnchecked(src, srcPos, dst, dstPos, length);
    486         }
    487     }
    488 
    489     /**
    490      * The float[] specialized, unchecked, native version of
    491      * arraycopy(). This assumes error checking has been done.
    492      */
    493     private static native void arraycopyFloatUnchecked(float[] src, int srcPos,
    494         float[] dst, int dstPos, int length);
    495 
    496     /**
    497      * The short array length threshold below which to use a Java
    498      * (non-native) version of arraycopy() instead of the native
    499      * version. See b/7103825.
    500      */
    501     private static final int ARRAYCOPY_SHORT_DOUBLE_ARRAY_THRESHOLD = 32;
    502 
    503     /**
    504      * The double[] specialized version of arraycopy().
    505      *
    506      * @hide internal use only
    507      */
    508     public static void arraycopy(double[] src, int srcPos, double[] dst, int dstPos, int length) {
    509         if (src == null) {
    510             throw new NullPointerException("src == null");
    511         }
    512         if (dst == null) {
    513             throw new NullPointerException("dst == null");
    514         }
    515         if (srcPos < 0 || dstPos < 0 || length < 0 ||
    516             srcPos > src.length - length || dstPos > dst.length - length) {
    517             throw new ArrayIndexOutOfBoundsException(
    518                 "src.length=" + src.length + " srcPos=" + srcPos +
    519                 " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
    520         }
    521         if (length <= ARRAYCOPY_SHORT_DOUBLE_ARRAY_THRESHOLD) {
    522             // Copy double by double for shorter arrays.
    523             if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
    524                 // Copy backward (to avoid overwriting elements before
    525                 // they are copied in case of an overlap on the same
    526                 // array.)
    527                 for (int i = length - 1; i >= 0; --i) {
    528                     dst[dstPos + i] = src[srcPos + i];
    529                 }
    530             } else {
    531                 // Copy forward.
    532                 for (int i = 0; i < length; ++i) {
    533                     dst[dstPos + i] = src[srcPos + i];
    534                 }
    535             }
    536         } else {
    537             // Call the native version for floater arrays.
    538             arraycopyDoubleUnchecked(src, srcPos, dst, dstPos, length);
    539         }
    540     }
    541 
    542     /**
    543      * The double[] specialized, unchecked, native version of
    544      * arraycopy(). This assumes error checking has been done.
    545      */
    546     private static native void arraycopyDoubleUnchecked(double[] src, int srcPos,
    547         double[] dst, int dstPos, int length);
    548 
    549     /**
    550      * The short array length threshold below which to use a Java
    551      * (non-native) version of arraycopy() instead of the native
    552      * version. See b/7103825.
    553      */
    554     private static final int ARRAYCOPY_SHORT_BOOLEAN_ARRAY_THRESHOLD = 32;
    555 
    556     /**
    557      * The boolean[] specialized version of arraycopy().
    558      *
    559      * @hide internal use only
    560      */
    561     public static void arraycopy(boolean[] src, int srcPos, boolean[] dst, int dstPos, int length) {
    562         if (src == null) {
    563             throw new NullPointerException("src == null");
    564         }
    565         if (dst == null) {
    566             throw new NullPointerException("dst == null");
    567         }
    568         if (srcPos < 0 || dstPos < 0 || length < 0 ||
    569             srcPos > src.length - length || dstPos > dst.length - length) {
    570             throw new ArrayIndexOutOfBoundsException(
    571                 "src.length=" + src.length + " srcPos=" + srcPos +
    572                 " dst.length=" + dst.length + " dstPos=" + dstPos + " length=" + length);
    573         }
    574         if (length <= ARRAYCOPY_SHORT_BOOLEAN_ARRAY_THRESHOLD) {
    575             // Copy boolean by boolean for shorter arrays.
    576             if (src == dst && srcPos < dstPos && dstPos < srcPos + length) {
    577                 // Copy backward (to avoid overwriting elements before
    578                 // they are copied in case of an overlap on the same
    579                 // array.)
    580                 for (int i = length - 1; i >= 0; --i) {
    581                     dst[dstPos + i] = src[srcPos + i];
    582                 }
    583             } else {
    584                 // Copy forward.
    585                 for (int i = 0; i < length; ++i) {
    586                     dst[dstPos + i] = src[srcPos + i];
    587                 }
    588             }
    589         } else {
    590             // Call the native version for floater arrays.
    591             arraycopyBooleanUnchecked(src, srcPos, dst, dstPos, length);
    592         }
    593     }
    594 
    595     /**
    596      * The boolean[] specialized, unchecked, native version of
    597      * arraycopy(). This assumes error checking has been done.
    598      */
    599     private static native void arraycopyBooleanUnchecked(boolean[] src, int srcPos,
    600         boolean[] dst, int dstPos, int length);
    601 
    602     /**
    603      * Returns the current time in milliseconds since January 1, 1970 00:00:00.0 UTC.
    604      *
    605      * <p>This method always returns UTC times, regardless of the system's time zone.
    606      * This is often called "Unix time" or "epoch time".
    607      * Use a {@link java.text.DateFormat} instance to format this time for display to a human.
    608      *
    609      * <p>This method shouldn't be used for measuring timeouts or
    610      * other elapsed time measurements, as changing the system time can affect
    611      * the results. Use {@link #nanoTime} for that.
    612      */
    613     public static native long currentTimeMillis();
    614 
    615     /**
    616      * Returns the current timestamp of the most precise timer available on the
    617      * local system, in nanoseconds. Equivalent to Linux's {@code CLOCK_MONOTONIC}.
    618      *
    619      * <p>This timestamp should only be used to measure a duration by comparing it
    620      * against another timestamp on the same device.
    621      * Values returned by this method do not have a defined correspondence to
    622      * wall clock times; the zero value is typically whenever the device last booted.
    623      * Use {@link #currentTimeMillis} if you want to know what time it is.
    624      */
    625     public static native long nanoTime();
    626 
    627     /**
    628      * Causes the VM to stop running and the program to exit with the given exit status.
    629      * If {@link #runFinalizersOnExit(boolean)} has been previously invoked with a
    630      * {@code true} argument, then all objects will be properly
    631      * garbage-collected and finalized first.
    632      */
    633     public static void exit(int code) {
    634         Runtime.getRuntime().exit(code);
    635     }
    636 
    637     /**
    638      * Indicates to the VM that it would be a good time to run the
    639      * garbage collector. Note that this is a hint only. There is no guarantee
    640      * that the garbage collector will actually be run.
    641      */
    642     public static void gc() {
    643         boolean shouldRunGC;
    644         synchronized(lock) {
    645             shouldRunGC = justRanFinalization;
    646             if (shouldRunGC) {
    647                 justRanFinalization = false;
    648             } else {
    649                 runGC = true;
    650             }
    651         }
    652         if (shouldRunGC) {
    653             Runtime.getRuntime().gc();
    654         }
    655     }
    656 
    657     /**
    658      * Returns the value of the environment variable with the given name, or null if no such
    659      * variable exists.
    660      */
    661     public static String getenv(String name) {
    662         if (name == null) {
    663             throw new NullPointerException("name == null");
    664         }
    665         return Libcore.os.getenv(name);
    666     }
    667 
    668     /**
    669      * Returns an unmodifiable map of all environment variables to their values.
    670      */
    671     public static Map<String, String> getenv() {
    672         Map<String, String> map = new HashMap<String, String>();
    673         for (String entry : Libcore.os.environ()) {
    674             int index = entry.indexOf('=');
    675             if (index != -1) {
    676                 map.put(entry.substring(0, index), entry.substring(index + 1));
    677             }
    678         }
    679         return new SystemEnvironment(map);
    680     }
    681 
    682     /**
    683      * Returns the inherited channel from the creator of the current virtual
    684      * machine.
    685      *
    686      * @return the inherited {@link Channel} or {@code null} if none exists.
    687      * @throws IOException
    688      *             if an I/O error occurred.
    689      * @see SelectorProvider
    690      * @see SelectorProvider#inheritedChannel()
    691      */
    692     public static Channel inheritedChannel() throws IOException {
    693         return SelectorProvider.provider().inheritedChannel();
    694     }
    695 
    696     /**
    697      * Returns the system properties. Note that this is not a copy, so that
    698      * changes made to the returned Properties object will be reflected in
    699      * subsequent calls to getProperty and getProperties.
    700      *
    701      * @return the system properties.
    702      */
    703     public static Properties getProperties() {
    704         return systemProperties;
    705     }
    706 
    707     private static Properties initUnchangeableSystemProperties() {
    708         VMRuntime runtime = VMRuntime.getRuntime();
    709         Properties p = new Properties();
    710 
    711         String projectUrl = "http://www.android.com/";
    712         String projectName = "The Android Project";
    713 
    714         p.put("java.boot.class.path", runtime.bootClassPath());
    715         p.put("java.class.path", runtime.classPath());
    716 
    717         // None of these four are meaningful on Android, but these keys are guaranteed
    718         // to be present for System.getProperty. For java.class.version, we use the maximum
    719         // class file version that dx currently supports.
    720         p.put("java.class.version", "50.0");
    721         p.put("java.compiler", "");
    722         p.put("java.ext.dirs", "");
    723         p.put("java.version", "0");
    724 
    725         // TODO: does this make any sense? Should we just leave java.home unset?
    726         String javaHome = getenv("JAVA_HOME");
    727         if (javaHome == null) {
    728             javaHome = "/system";
    729         }
    730         p.put("java.home", javaHome);
    731 
    732         p.put("java.specification.name", "Dalvik Core Library");
    733         p.put("java.specification.vendor", projectName);
    734         p.put("java.specification.version", "0.9");
    735 
    736         p.put("java.vendor", projectName);
    737         p.put("java.vendor.url", projectUrl);
    738         p.put("java.vm.name", "Dalvik");
    739         p.put("java.vm.specification.name", "Dalvik Virtual Machine Specification");
    740         p.put("java.vm.specification.vendor", projectName);
    741         p.put("java.vm.specification.version", "0.9");
    742         p.put("java.vm.vendor", projectName);
    743         p.put("java.vm.version", runtime.vmVersion());
    744 
    745         p.put("file.separator", "/");
    746         p.put("line.separator", "\n");
    747         p.put("path.separator", ":");
    748 
    749         p.put("java.runtime.name", "Android Runtime");
    750         p.put("java.runtime.version", "0.9");
    751         p.put("java.vm.vendor.url", projectUrl);
    752 
    753         p.put("file.encoding", "UTF-8");
    754         p.put("user.language", "en");
    755         p.put("user.region", "US");
    756 
    757         try {
    758             StructPasswd passwd = Libcore.os.getpwuid(Libcore.os.getuid());
    759             p.put("user.name", passwd.pw_name);
    760         } catch (ErrnoException exception) {
    761             throw new AssertionError(exception);
    762         }
    763 
    764         StructUtsname info = Libcore.os.uname();
    765         p.put("os.arch", info.machine);
    766         p.put("os.name", info.sysname);
    767         p.put("os.version", info.release);
    768 
    769         // Undocumented Android-only properties.
    770         p.put("android.icu.library.version", ICU.getIcuVersion());
    771         p.put("android.icu.unicode.version", ICU.getUnicodeVersion());
    772         p.put("android.icu.cldr.version", ICU.getCldrVersion());
    773 
    774         parsePropertyAssignments(p, specialProperties());
    775 
    776         // Override built-in properties with settings from the command line.
    777         parsePropertyAssignments(p, runtime.properties());
    778         return p;
    779     }
    780 
    781     /**
    782      * Inits an unchangeable system property with the given value.
    783      * This is useful when the environment needs to change under native bridge emulation.
    784      */
    785     private static void initUnchangeableSystemProperty(String name, String value) {
    786         checkPropertyName(name);
    787         unchangeableSystemProperties.put(name, value);
    788     }
    789 
    790     private static void setDefaultChangeableProperties(Properties p) {
    791         // On Android, each app gets its own temporary directory.
    792         // (See android.app.ActivityThread.) This is just a fallback default,
    793         // useful only on the host.
    794         p.put("java.io.tmpdir", "/tmp");
    795 
    796         // Android has always had an empty "user.home" (see docs for getProperty).
    797         // This is not useful for normal android apps which need to use android specific
    798         // APIs such as {@code Context.getFilesDir} and {@code Context.getCacheDir} but
    799         // we make it changeable for backward compatibility, so that they can change it
    800         // to a writeable location if required.
    801         p.put("user.home", "");
    802     }
    803 
    804     private static Properties createSystemProperties() {
    805         Properties p = new PropertiesWithNonOverrideableDefaults(unchangeableSystemProperties);
    806         setDefaultChangeableProperties(p);
    807         return p;
    808     }
    809 
    810     /**
    811      * Returns an array of "key=value" strings containing information not otherwise
    812      * easily available, such as #defined library versions.
    813      */
    814     private static native String[] specialProperties();
    815 
    816     /**
    817      * Adds each element of 'assignments' to 'p', treating each element as an
    818      * assignment in the form "key=value".
    819      */
    820     private static void parsePropertyAssignments(Properties p, String[] assignments) {
    821         for (String assignment : assignments) {
    822             int split = assignment.indexOf('=');
    823             String key = assignment.substring(0, split);
    824             String value = assignment.substring(split + 1);
    825             p.put(key, value);
    826         }
    827     }
    828 
    829     /**
    830      * Returns the value of a particular system property or {@code null} if no
    831      * such property exists.
    832      *
    833      * <p>The following properties are always provided by the Dalvik VM <b>and
    834      * cannot be modified</b>:
    835      * <p><table BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
    836      * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
    837      *     <td><b>Name</b></td>        <td><b>Meaning</b></td>                    <td><b>Example</b></td></tr>
    838      * <tr><td>file.separator</td>     <td>{@link java.io.File#separator}</td>    <td>{@code /}</td></tr>
    839      *
    840      * <tr><td>java.class.path</td>    <td>System class path</td>                 <td>{@code .}</td></tr>
    841      * <tr><td>java.class.version</td> <td>(Not useful on Android)</td>           <td>{@code 50.0}</td></tr>
    842      * <tr><td>java.compiler</td>      <td>(Not useful on Android)</td>           <td>Empty</td></tr>
    843      * <tr><td>java.ext.dirs</td>      <td>(Not useful on Android)</td>           <td>Empty</td></tr>
    844      * <tr><td>java.home</td>          <td>Location of the VM on the file system</td> <td>{@code /system}</td></tr>
    845      * <tr><td>java.io.tmpdir</td>     <td>See {@link java.io.File#createTempFile}</td> <td>{@code /sdcard}</td></tr>
    846      * <tr><td>java.library.path</td>  <td>Search path for JNI libraries</td>     <td>{@code /vendor/lib:/system/lib}</td></tr>
    847      * <tr><td>java.vendor</td>        <td>Human-readable VM vendor</td>          <td>{@code The Android Project}</td></tr>
    848      * <tr><td>java.vendor.url</td>    <td>URL for VM vendor's web site</td>      <td>{@code http://www.android.com/}</td></tr>
    849      * <tr><td>java.version</td>       <td>(Not useful on Android)</td>           <td>{@code 0}</td></tr>
    850      *
    851      * <tr><td>java.specification.version</td>    <td>VM libraries version</td>        <td>{@code 0.9}</td></tr>
    852      * <tr><td>java.specification.vendor</td>     <td>VM libraries vendor</td>         <td>{@code The Android Project}</td></tr>
    853      * <tr><td>java.specification.name</td>       <td>VM libraries name</td>           <td>{@code Dalvik Core Library}</td></tr>
    854      * <tr><td>java.vm.version</td>               <td>VM implementation version</td>   <td>{@code 1.2.0}</td></tr>
    855      * <tr><td>java.vm.vendor</td>                <td>VM implementation vendor</td>    <td>{@code The Android Project}</td></tr>
    856      * <tr><td>java.vm.name</td>                  <td>VM implementation name</td>      <td>{@code Dalvik}</td></tr>
    857      * <tr><td>java.vm.specification.version</td> <td>VM specification version</td>    <td>{@code 0.9}</td></tr>
    858      * <tr><td>java.vm.specification.vendor</td>  <td>VM specification vendor</td>     <td>{@code The Android Project}</td></tr>
    859      * <tr><td>java.vm.specification.name</td>    <td>VM specification name</td>       <td>{@code Dalvik Virtual Machine Specification}</td></tr>
    860      *
    861      * <tr><td>line.separator</td>     <td>The system line separator</td>         <td>{@code \n}</td></tr>
    862      *
    863      * <tr><td>os.arch</td>            <td>OS architecture</td>                   <td>{@code armv7l}</td></tr>
    864      * <tr><td>os.name</td>            <td>OS (kernel) name</td>                  <td>{@code Linux}</td></tr>
    865      * <tr><td>os.version</td>         <td>OS (kernel) version</td>               <td>{@code 2.6.32.9-g103d848}</td></tr>
    866      *
    867      * <tr><td>path.separator</td>     <td>See {@link java.io.File#pathSeparator}</td> <td>{@code :}</td></tr>
    868      *
    869      * <tr><td>user.dir</td>           <td>Base of non-absolute paths</td>        <td>{@code /}</td></tr>
    870      * <tr><td>user.home</td>          <td>(Not useful on Android)</td>           <td>Empty</td></tr>
    871      * <tr><td>user.name</td>          <td>(Not useful on Android)</td>           <td>Empty</td></tr>
    872      *
    873      * </table>
    874      *
    875      * <p>It is an error to override anyone of these properties. Any attempt to
    876      * do so will leave their values unchanged.
    877      *
    878      * @param propertyName
    879      *            the name of the system property to look up.
    880      * @return the value of the specified system property or {@code null} if the
    881      *         property doesn't exist.
    882      */
    883     public static String getProperty(String propertyName) {
    884         return getProperty(propertyName, null);
    885     }
    886 
    887     /**
    888      * Returns the value of a particular system property. The {@code
    889      * defaultValue} will be returned if no such property has been found.
    890      */
    891     public static String getProperty(String name, String defaultValue) {
    892         checkPropertyName(name);
    893         return systemProperties.getProperty(name, defaultValue);
    894     }
    895 
    896     /**
    897      * Sets the value of a particular system property. Most system properties
    898      * are read only and cannot be cleared or modified. See {@link #setProperty} for a
    899      * list of such properties.
    900      *
    901      * @return the old value of the property or {@code null} if the property
    902      *         didn't exist.
    903      */
    904     public static String setProperty(String name, String value) {
    905         checkPropertyName(name);
    906         return (String) systemProperties.setProperty(name, value);
    907     }
    908 
    909     /**
    910      * Removes a specific system property. Most system properties
    911      * are read only and cannot be cleared or modified. See {@link #setProperty} for a
    912      * list of such properties.
    913      *
    914      * @return the property value or {@code null} if the property didn't exist.
    915      * @throws NullPointerException
    916      *             if the argument is {@code null}.
    917      * @throws IllegalArgumentException
    918      *             if the argument is empty.
    919      */
    920     public static String clearProperty(String name) {
    921         checkPropertyName(name);
    922         return (String) systemProperties.remove(name);
    923     }
    924 
    925     private static void checkPropertyName(String name) {
    926         if (name == null) {
    927             throw new NullPointerException("name == null");
    928         }
    929         if (name.isEmpty()) {
    930             throw new IllegalArgumentException("name is empty");
    931         }
    932     }
    933 
    934     /**
    935      * Returns the {@link java.io.Console} associated with this VM, or null.
    936      * Not all VMs will have an associated console. A console is typically only
    937      * available for programs run from the command line.
    938      * @since 1.6
    939      */
    940     public static Console console() {
    941         return Console.getConsole();
    942     }
    943 
    944     /**
    945      * Returns null. Android does not use {@code SecurityManager}. This method
    946      * is only provided for source compatibility.
    947      *
    948      * @return null
    949      */
    950     public static SecurityManager getSecurityManager() {
    951         return null;
    952     }
    953 
    954     /**
    955      * Returns an integer hash code for the parameter. The hash code returned is
    956      * the same one that would be returned by the method {@code
    957      * java.lang.Object.hashCode()}, whether or not the object's class has
    958      * overridden hashCode(). The hash code for {@code null} is {@code 0}.
    959      *
    960      * @param anObject
    961      *            the object to calculate the hash code.
    962      * @return the hash code for the given object.
    963      * @see java.lang.Object#hashCode
    964      */
    965     public static native int identityHashCode(Object anObject);
    966 
    967     /**
    968      * Returns the system's line separator. On Android, this is {@code "\n"}. The value
    969      * comes from the value of the {@code line.separator} system property when the VM
    970      * starts. Later changes to the property will not affect the value returned by this
    971      * method.
    972      * @since 1.7
    973      */
    974     public static String lineSeparator() {
    975         return lineSeparator;
    976     }
    977 
    978     /**
    979      * See {@link Runtime#load}.
    980      */
    981     public static void load(String pathName) {
    982         Runtime.getRuntime().load(pathName, VMStack.getCallingClassLoader());
    983     }
    984 
    985     /**
    986      * See {@link Runtime#loadLibrary}.
    987      */
    988     public static void loadLibrary(String libName) {
    989         Runtime.getRuntime().loadLibrary(libName, VMStack.getCallingClassLoader());
    990     }
    991 
    992     /**
    993      * @hide internal use only
    994      */
    995     public static void logE(String message) {
    996         log('E', message, null);
    997     }
    998 
    999     /**
   1000      * @hide internal use only
   1001      */
   1002     public static void logE(String message, Throwable th) {
   1003         log('E', message, th);
   1004     }
   1005 
   1006     /**
   1007      * @hide internal use only
   1008      */
   1009     public static void logI(String message) {
   1010         log('I', message, null);
   1011     }
   1012 
   1013     /**
   1014      * @hide internal use only
   1015      */
   1016     public static void logI(String message, Throwable th) {
   1017         log('I', message, th);
   1018     }
   1019 
   1020     /**
   1021      * @hide internal use only
   1022      */
   1023     public static void logW(String message) {
   1024         log('W', message, null);
   1025     }
   1026 
   1027     /**
   1028      * @hide internal use only
   1029      */
   1030     public static void logW(String message, Throwable th) {
   1031         log('W', message, th);
   1032     }
   1033 
   1034     private static native void log(char type, String message, Throwable th);
   1035 
   1036     /**
   1037      * Provides a hint to the VM that it would be useful to attempt
   1038      * to perform any outstanding object finalization.
   1039      */
   1040     public static void runFinalization() {
   1041         boolean shouldRunGC;
   1042         synchronized(lock) {
   1043             shouldRunGC = runGC;
   1044             runGC = false;
   1045         }
   1046         if (shouldRunGC) {
   1047             Runtime.getRuntime().gc();
   1048         }
   1049         Runtime.getRuntime().runFinalization();
   1050         synchronized(lock) {
   1051             justRanFinalization = true;
   1052         }
   1053     }
   1054 
   1055     /**
   1056      * Ensures that, when the VM is about to exit, all objects are
   1057      * finalized. Note that all finalization which occurs when the system is
   1058      * exiting is performed after all running threads have been terminated.
   1059      *
   1060      * @param flag
   1061      *            the flag determines if finalization on exit is enabled.
   1062      * @deprecated This method is unsafe.
   1063      */
   1064     @SuppressWarnings("deprecation")
   1065     @Deprecated
   1066     public static void runFinalizersOnExit(boolean flag) {
   1067         Runtime.runFinalizersOnExit(flag);
   1068     }
   1069 
   1070     /**
   1071      * Attempts to set all system properties. Copies all properties from
   1072      * {@code p} and discards system properties that are read only and cannot
   1073      * be modified. See {@link #setProperty} for a list of such properties.
   1074      */
   1075     public static void setProperties(Properties p) {
   1076         PropertiesWithNonOverrideableDefaults userProperties =
   1077                 new PropertiesWithNonOverrideableDefaults(unchangeableSystemProperties);
   1078         if (p != null) {
   1079             userProperties.putAll(p);
   1080         } else {
   1081             // setProperties(null) is documented to restore defaults.
   1082             setDefaultChangeableProperties(userProperties);
   1083         }
   1084 
   1085         systemProperties = userProperties;
   1086     }
   1087 
   1088     /**
   1089      * Throws {@code SecurityException}.
   1090      *
   1091      * <p>Security managers do <i>not</i> provide a secure environment for
   1092      * executing untrusted code and are unsupported on Android. Untrusted code
   1093      * cannot be safely isolated within a single VM on Android, so this method
   1094      * <i>always</i> throws a {@code SecurityException}.
   1095      *
   1096      * @param sm a security manager
   1097      * @throws SecurityException always
   1098      */
   1099     public static void setSecurityManager(SecurityManager sm) {
   1100         if (sm != null) {
   1101             throw new SecurityException();
   1102         }
   1103     }
   1104 
   1105     /**
   1106      * Returns the platform specific file name format for the shared library
   1107      * named by the argument. On Android, this would turn {@code "MyLibrary"} into
   1108      * {@code "libMyLibrary.so"}.
   1109      */
   1110     public static native String mapLibraryName(String nickname);
   1111 
   1112     /**
   1113      * Used to set System.err, System.in, and System.out.
   1114      */
   1115     private static native void setFieldImpl(String field, String signature, Object stream);
   1116 
   1117     /**
   1118      * A properties class that prohibits changes to any of the properties
   1119      * contained in its defaults.
   1120      */
   1121     static final class PropertiesWithNonOverrideableDefaults extends Properties {
   1122         PropertiesWithNonOverrideableDefaults(Properties defaults) {
   1123             super(defaults);
   1124         }
   1125 
   1126         @Override
   1127         public Object put(Object key, Object value) {
   1128             if (defaults.containsKey(key)) {
   1129                 logE("Ignoring attempt to set property \"" + key +
   1130                         "\" to value \"" + value + "\".");
   1131                 return defaults.get(key);
   1132             }
   1133 
   1134             return super.put(key, value);
   1135         }
   1136 
   1137         @Override
   1138         public Object remove(Object key) {
   1139             if (defaults.containsKey(key)) {
   1140                 logE("Ignoring attempt to remove property \"" + key + "\".");
   1141                 return null;
   1142             }
   1143 
   1144             return super.remove(key);
   1145         }
   1146     }
   1147 
   1148     /**
   1149      * The unmodifiable environment variables map. System.getenv() specifies
   1150      * that this map must throw when passed non-String keys.
   1151      */
   1152     static class SystemEnvironment extends AbstractMap<String, String> {
   1153         private final Map<String, String> map;
   1154 
   1155         public SystemEnvironment(Map<String, String> map) {
   1156             this.map = Collections.unmodifiableMap(map);
   1157         }
   1158 
   1159         @Override public Set<Entry<String, String>> entrySet() {
   1160             return map.entrySet();
   1161         }
   1162 
   1163         @Override public String get(Object key) {
   1164             return map.get(toNonNullString(key));
   1165         }
   1166 
   1167         @Override public boolean containsKey(Object key) {
   1168             return map.containsKey(toNonNullString(key));
   1169         }
   1170 
   1171         @Override public boolean containsValue(Object value) {
   1172             return map.containsValue(toNonNullString(value));
   1173         }
   1174 
   1175         private String toNonNullString(Object o) {
   1176             if (o == null) {
   1177                 throw new NullPointerException("o == null");
   1178             }
   1179             return (String) o;
   1180         }
   1181     }
   1182 }
   1183