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