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.Map;
54import java.util.Properties;
55import java.util.Set;
56import libcore.icu.ICU;
57import 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 */
67public 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