1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 /*
18  * Copyright (C) 2008 The Android Open Source Project
19  *
20  * Licensed under the Apache License, Version 2.0 (the "License");
21  * you may not use this file except in compliance with the License.
22  * You may obtain a copy of the License at
23  *
24  *      http://www.apache.org/licenses/LICENSE-2.0
25  *
26  * Unless required by applicable law or agreed to in writing, software
27  * distributed under the License is distributed on an "AS IS" BASIS,
28  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29  * See the License for the specific language governing permissions and
30  * limitations under the License.
31  */
32 
33 package java.lang;
34 
35 import android.system.ErrnoException;
36 import android.system.StructPasswd;
37 import android.system.StructUtsname;
38 import dalvik.system.VMRuntime;
39 import dalvik.system.VMStack;
40 import java.io.BufferedInputStream;
41 import java.io.Console;
42 import java.io.FileDescriptor;
43 import java.io.FileInputStream;
44 import java.io.FileOutputStream;
45 import java.io.InputStream;
46 import java.io.IOException;
47 import java.io.PrintStream;
48 import java.nio.channels.Channel;
49 import java.nio.channels.spi.SelectorProvider;
50 import java.util.AbstractMap;
51 import java.util.Collections;
52 import java.util.HashMap;
53 import java.util.Map;
54 import java.util.Properties;
55 import java.util.Set;
56 import libcore.icu.ICU;
57 import libcore.io.Libcore;
58 
59 /**
60  * Provides access to system-related information and resources including
61  * standard input and output. Enables clients to dynamically load native
62  * libraries. All methods of this class are accessed in a static way and the
63  * class itself can not be instantiated.
64  *
65  * @see Runtime
66  */
67 public final class System {
68 
69     /**
70      * Default input stream.
71      */
72     public static final InputStream in;
73 
74     /**
75      * Default output stream.
76      */
77     public static final PrintStream out;
78 
79     /**
80      * Default error output stream.
81      */
82     public static final PrintStream err;
83 
84     private static final String lineSeparator;
85     private static final Properties unchangeableSystemProperties;
86     private static Properties systemProperties;
87 
88     /**
89      * Dedicated lock for GC / Finalization logic.
90      */
91     private static final Object lock = new Object();
92 
93     /**
94      * Whether or not we need to do a GC before running the finalizers.
95      */
96     private static boolean runGC;
97 
98     /**
99      * If we just ran finalization, we might want to do a GC to free the finalized objects.
100      * This lets us do gc/runFinlization/gc sequences but prevents back to back System.gc().
101      */
102     private static boolean justRanFinalization;
103 
104     static {
105         err = new PrintStream(new FileOutputStream(FileDescriptor.err));
106         out = new PrintStream(new FileOutputStream(FileDescriptor.out));
107         in = new BufferedInputStream(new FileInputStream(FileDescriptor.in));
108         unchangeableSystemProperties = initUnchangeableSystemProperties();
109         systemProperties = createSystemProperties();
110         lineSeparator = System.getProperty("line.separator");
111     }
112 
113     /**
114      * Sets the standard input stream to the given user defined input stream.
115      *
116      * @param newIn
117      *            the user defined input stream to set as the standard input
118      *            stream.
119      */
setIn(InputStream newIn)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      */
setOut(PrintStream newOut)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      */
setErr(PrintStream newErr)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      */
System()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 
arraycopy(Object src, int srcPos, Object dst, int dstPos, int length)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      */
arraycopy(char[] src, int srcPos, char[] dst, int dstPos, int length)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      */
arraycopyCharUnchecked(char[] src, int srcPos, char[] dst, int dstPos, int length)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      */
arraycopy(byte[] src, int srcPos, byte[] dst, int dstPos, int length)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      */
arraycopyByteUnchecked(byte[] src, int srcPos, byte[] dst, int dstPos, int length)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      */
arraycopy(short[] src, int srcPos, short[] dst, int dstPos, int length)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      */
arraycopyShortUnchecked(short[] src, int srcPos, short[] dst, int dstPos, int length)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      */
arraycopy(int[] src, int srcPos, int[] dst, int dstPos, int length)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      */
arraycopyIntUnchecked(int[] src, int srcPos, int[] dst, int dstPos, int length)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      */
arraycopy(long[] src, int srcPos, long[] dst, int dstPos, int length)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      */
arraycopyLongUnchecked(long[] src, int srcPos, long[] dst, int dstPos, int length)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      */
arraycopy(float[] src, int srcPos, float[] dst, int dstPos, int length)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      */
arraycopyFloatUnchecked(float[] src, int srcPos, float[] dst, int dstPos, int length)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      */
arraycopy(double[] src, int srcPos, double[] dst, int dstPos, int length)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      */
arraycopyDoubleUnchecked(double[] src, int srcPos, double[] dst, int dstPos, int length)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      */
arraycopy(boolean[] src, int srcPos, boolean[] dst, int dstPos, int length)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      */
arraycopyBooleanUnchecked(boolean[] src, int srcPos, boolean[] dst, int dstPos, int length)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      */
currentTimeMillis()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      */
nanoTime()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      */
exit(int code)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      */
gc()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      */
getenv(String name)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      */
getenv()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      */
inheritedChannel()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      */
getProperties()703     public static Properties getProperties() {
704         return systemProperties;
705     }
706 
initUnchangeableSystemProperties()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      */
initUnchangeableSystemProperty(String name, String value)785     private static void initUnchangeableSystemProperty(String name, String value) {
786         checkPropertyName(name);
787         unchangeableSystemProperties.put(name, value);
788     }
789 
setDefaultChangeableProperties(Properties p)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 
createSystemProperties()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      */
specialProperties()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      */
parsePropertyAssignments(Properties p, String[] assignments)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:</p>
834      * <p><table BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY="">
835      * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor">
836      *     <td><b>Name</b></td>        <td><b>Meaning</b></td>                    <td><b>Example</b></td></tr>
837      * <tr><td>file.separator</td>     <td>{@link java.io.File#separator}</td>    <td>{@code /}</td></tr>
838      *
839      * <tr><td>java.class.path</td>    <td>System class path</td>                 <td>{@code .}</td></tr>
840      * <tr><td>java.class.version</td> <td>(Not useful on Android)</td>           <td>{@code 50.0}</td></tr>
841      * <tr><td>java.compiler</td>      <td>(Not useful on Android)</td>           <td>Empty</td></tr>
842      * <tr><td>java.ext.dirs</td>      <td>(Not useful on Android)</td>           <td>Empty</td></tr>
843      * <tr><td>java.home</td>          <td>Location of the VM on the file system</td> <td>{@code /system}</td></tr>
844      * <tr><td>java.io.tmpdir</td>     <td>See {@link java.io.File#createTempFile}</td> <td>{@code /sdcard}</td></tr>
845      * <tr><td>java.library.path</td>  <td>Search path for JNI libraries</td>     <td>{@code /vendor/lib:/system/lib}</td></tr>
846      * <tr><td>java.vendor</td>        <td>Human-readable VM vendor</td>          <td>{@code The Android Project}</td></tr>
847      * <tr><td>java.vendor.url</td>    <td>URL for VM vendor's web site</td>      <td>{@code http://www.android.com/}</td></tr>
848      * <tr><td>java.version</td>       <td>(Not useful on Android)</td>           <td>{@code 0}</td></tr>
849      *
850      * <tr><td>java.specification.version</td>    <td>VM libraries version</td>        <td>{@code 0.9}</td></tr>
851      * <tr><td>java.specification.vendor</td>     <td>VM libraries vendor</td>         <td>{@code The Android Project}</td></tr>
852      * <tr><td>java.specification.name</td>       <td>VM libraries name</td>           <td>{@code Dalvik Core Library}</td></tr>
853      * <tr><td>java.vm.version</td>               <td>VM implementation version</td>   <td>{@code 1.2.0}</td></tr>
854      * <tr><td>java.vm.vendor</td>                <td>VM implementation vendor</td>    <td>{@code The Android Project}</td></tr>
855      * <tr><td>java.vm.name</td>                  <td>VM implementation name</td>      <td>{@code Dalvik}</td></tr>
856      * <tr><td>java.vm.specification.version</td> <td>VM specification version</td>    <td>{@code 0.9}</td></tr>
857      * <tr><td>java.vm.specification.vendor</td>  <td>VM specification vendor</td>     <td>{@code The Android Project}</td></tr>
858      * <tr><td>java.vm.specification.name</td>    <td>VM specification name</td>       <td>{@code Dalvik Virtual Machine Specification}</td></tr>
859      *
860      * <tr><td>line.separator</td>     <td>The system line separator</td>         <td>{@code \n}</td></tr>
861      *
862      * <tr><td>os.arch</td>            <td>OS architecture</td>                   <td>{@code armv7l}</td></tr>
863      * <tr><td>os.name</td>            <td>OS (kernel) name</td>                  <td>{@code Linux}</td></tr>
864      * <tr><td>os.version</td>         <td>OS (kernel) version</td>               <td>{@code 2.6.32.9-g103d848}</td></tr>
865      *
866      * <tr><td>path.separator</td>     <td>See {@link java.io.File#pathSeparator}</td> <td>{@code :}</td></tr>
867      *
868      * <tr><td>user.dir</td>           <td>Base of non-absolute paths</td>        <td>{@code /}</td></tr>
869      * <tr><td>user.home</td>          <td>(Not useful on Android)</td>           <td>Empty</td></tr>
870      * <tr><td>user.name</td>          <td>(Not useful on Android)</td>           <td>Empty</td></tr>
871      *
872      * </table>
873      *
874      * <p> All of the above properties except for {@code user.home} and {@code java.io.tmpdir}
875      * <b>cannot be modified</b>. Any attempt to change them will be a no-op.
876      *
877      * @param propertyName
878      *            the name of the system property to look up.
879      * @return the value of the specified system property or {@code null} if the
880      *         property doesn't exist.
881      */
getProperty(String propertyName)882     public static String getProperty(String propertyName) {
883         return getProperty(propertyName, null);
884     }
885 
886     /**
887      * Returns the value of a particular system property. The {@code
888      * defaultValue} will be returned if no such property has been found.
889      */
getProperty(String name, String defaultValue)890     public static String getProperty(String name, String defaultValue) {
891         checkPropertyName(name);
892         return systemProperties.getProperty(name, defaultValue);
893     }
894 
895     /**
896      * Sets the value of a particular system property. Most system properties
897      * are read only and cannot be cleared or modified. See {@link #getProperty} for a
898      * list of such properties.
899      *
900      * @return the old value of the property or {@code null} if the property
901      *         didn't exist.
902      */
setProperty(String name, String value)903     public static String setProperty(String name, String value) {
904         checkPropertyName(name);
905         return (String) systemProperties.setProperty(name, value);
906     }
907 
908     /**
909      * Removes a specific system property. Most system properties
910      * are read only and cannot be cleared or modified. See {@link #getProperty} for a
911      * list of such properties.
912      *
913      * @return the property value or {@code null} if the property didn't exist.
914      * @throws NullPointerException
915      *             if the argument is {@code null}.
916      * @throws IllegalArgumentException
917      *             if the argument is empty.
918      */
clearProperty(String name)919     public static String clearProperty(String name) {
920         checkPropertyName(name);
921         return (String) systemProperties.remove(name);
922     }
923 
checkPropertyName(String name)924     private static void checkPropertyName(String name) {
925         if (name == null) {
926             throw new NullPointerException("name == null");
927         }
928         if (name.isEmpty()) {
929             throw new IllegalArgumentException("name is empty");
930         }
931     }
932 
933     /**
934      * Returns the {@link java.io.Console} associated with this VM, or null.
935      * Not all VMs will have an associated console. A console is typically only
936      * available for programs run from the command line.
937      * @since 1.6
938      */
console()939     public static Console console() {
940         return Console.getConsole();
941     }
942 
943     /**
944      * Returns null. Android does not use {@code SecurityManager}. This method
945      * is only provided for source compatibility.
946      *
947      * @return null
948      */
getSecurityManager()949     public static SecurityManager getSecurityManager() {
950         return null;
951     }
952 
953     /**
954      * Returns an integer hash code for the parameter. The hash code returned is
955      * the same one that would be returned by the method {@code
956      * java.lang.Object.hashCode()}, whether or not the object's class has
957      * overridden hashCode(). The hash code for {@code null} is {@code 0}.
958      *
959      * @param anObject
960      *            the object to calculate the hash code.
961      * @return the hash code for the given object.
962      * @see java.lang.Object#hashCode
963      */
identityHashCode(Object anObject)964     public static native int identityHashCode(Object anObject);
965 
966     /**
967      * Returns the system's line separator. On Android, this is {@code "\n"}. The value
968      * comes from the value of the {@code line.separator} system property when the VM
969      * starts. Later changes to the property will not affect the value returned by this
970      * method.
971      * @since 1.7
972      */
lineSeparator()973     public static String lineSeparator() {
974         return lineSeparator;
975     }
976 
977     /**
978      * See {@link Runtime#load}.
979      */
load(String pathName)980     public static void load(String pathName) {
981         Runtime.getRuntime().load(pathName, VMStack.getCallingClassLoader());
982     }
983 
984     /**
985      * See {@link Runtime#loadLibrary}.
986      */
loadLibrary(String libName)987     public static void loadLibrary(String libName) {
988         Runtime.getRuntime().loadLibrary(libName, VMStack.getCallingClassLoader());
989     }
990 
991     /**
992      * @hide internal use only
993      */
logE(String message)994     public static void logE(String message) {
995         log('E', message, null);
996     }
997 
998     /**
999      * @hide internal use only
1000      */
logE(String message, Throwable th)1001     public static void logE(String message, Throwable th) {
1002         log('E', message, th);
1003     }
1004 
1005     /**
1006      * @hide internal use only
1007      */
logI(String message)1008     public static void logI(String message) {
1009         log('I', message, null);
1010     }
1011 
1012     /**
1013      * @hide internal use only
1014      */
logI(String message, Throwable th)1015     public static void logI(String message, Throwable th) {
1016         log('I', message, th);
1017     }
1018 
1019     /**
1020      * @hide internal use only
1021      */
logW(String message)1022     public static void logW(String message) {
1023         log('W', message, null);
1024     }
1025 
1026     /**
1027      * @hide internal use only
1028      */
logW(String message, Throwable th)1029     public static void logW(String message, Throwable th) {
1030         log('W', message, th);
1031     }
1032 
log(char type, String message, Throwable th)1033     private static native void log(char type, String message, Throwable th);
1034 
1035     /**
1036      * Provides a hint to the VM that it would be useful to attempt
1037      * to perform any outstanding object finalization.
1038      */
runFinalization()1039     public static void runFinalization() {
1040         boolean shouldRunGC;
1041         synchronized(lock) {
1042             shouldRunGC = runGC;
1043             runGC = false;
1044         }
1045         if (shouldRunGC) {
1046             Runtime.getRuntime().gc();
1047         }
1048         Runtime.getRuntime().runFinalization();
1049         synchronized(lock) {
1050             justRanFinalization = true;
1051         }
1052     }
1053 
1054     /**
1055      * Ensures that, when the VM is about to exit, all objects are
1056      * finalized. Note that all finalization which occurs when the system is
1057      * exiting is performed after all running threads have been terminated.
1058      *
1059      * @param flag
1060      *            the flag determines if finalization on exit is enabled.
1061      * @deprecated This method is unsafe.
1062      */
1063     @SuppressWarnings("deprecation")
1064     @Deprecated
runFinalizersOnExit(boolean flag)1065     public static void runFinalizersOnExit(boolean flag) {
1066         Runtime.runFinalizersOnExit(flag);
1067     }
1068 
1069     /**
1070      * Attempts to set all system properties. Copies all properties from
1071      * {@code p} and discards system properties that are read only and cannot
1072      * be modified. See {@link #getProperty} for a list of such properties.
1073      */
setProperties(Properties p)1074     public static void setProperties(Properties p) {
1075         PropertiesWithNonOverrideableDefaults userProperties =
1076                 new PropertiesWithNonOverrideableDefaults(unchangeableSystemProperties);
1077         if (p != null) {
1078             userProperties.putAll(p);
1079         } else {
1080             // setProperties(null) is documented to restore defaults.
1081             setDefaultChangeableProperties(userProperties);
1082         }
1083 
1084         systemProperties = userProperties;
1085     }
1086 
1087     /**
1088      * Throws {@code SecurityException}.
1089      *
1090      * <p>Security managers do <i>not</i> provide a secure environment for
1091      * executing untrusted code and are unsupported on Android. Untrusted code
1092      * cannot be safely isolated within a single VM on Android, so this method
1093      * <i>always</i> throws a {@code SecurityException}.
1094      *
1095      * @param sm a security manager
1096      * @throws SecurityException always
1097      */
setSecurityManager(SecurityManager sm)1098     public static void setSecurityManager(SecurityManager sm) {
1099         if (sm != null) {
1100             throw new SecurityException();
1101         }
1102     }
1103 
1104     /**
1105      * Returns the platform specific file name format for the shared library
1106      * named by the argument. On Android, this would turn {@code "MyLibrary"} into
1107      * {@code "libMyLibrary.so"}.
1108      */
mapLibraryName(String nickname)1109     public static native String mapLibraryName(String nickname);
1110 
1111     /**
1112      * Used to set System.err, System.in, and System.out.
1113      */
setFieldImpl(String field, String signature, Object stream)1114     private static native void setFieldImpl(String field, String signature, Object stream);
1115 
1116     /**
1117      * A properties class that prohibits changes to any of the properties
1118      * contained in its defaults.
1119      */
1120     static final class PropertiesWithNonOverrideableDefaults extends Properties {
PropertiesWithNonOverrideableDefaults(Properties defaults)1121         PropertiesWithNonOverrideableDefaults(Properties defaults) {
1122             super(defaults);
1123         }
1124 
1125         @Override
put(Object key, Object value)1126         public Object put(Object key, Object value) {
1127             if (defaults.containsKey(key)) {
1128                 logE("Ignoring attempt to set property \"" + key +
1129                         "\" to value \"" + value + "\".");
1130                 return defaults.get(key);
1131             }
1132 
1133             return super.put(key, value);
1134         }
1135 
1136         @Override
remove(Object key)1137         public Object remove(Object key) {
1138             if (defaults.containsKey(key)) {
1139                 logE("Ignoring attempt to remove property \"" + key + "\".");
1140                 return null;
1141             }
1142 
1143             return super.remove(key);
1144         }
1145     }
1146 
1147     /**
1148      * The unmodifiable environment variables map. System.getenv() specifies
1149      * that this map must throw when passed non-String keys.
1150      */
1151     static class SystemEnvironment extends AbstractMap<String, String> {
1152         private final Map<String, String> map;
1153 
SystemEnvironment(Map<String, String> map)1154         public SystemEnvironment(Map<String, String> map) {
1155             this.map = Collections.unmodifiableMap(map);
1156         }
1157 
entrySet()1158         @Override public Set<Entry<String, String>> entrySet() {
1159             return map.entrySet();
1160         }
1161 
get(Object key)1162         @Override public String get(Object key) {
1163             return map.get(toNonNullString(key));
1164         }
1165 
containsKey(Object key)1166         @Override public boolean containsKey(Object key) {
1167             return map.containsKey(toNonNullString(key));
1168         }
1169 
containsValue(Object value)1170         @Override public boolean containsValue(Object value) {
1171             return map.containsValue(toNonNullString(value));
1172         }
1173 
toNonNullString(Object o)1174         private String toNonNullString(Object o) {
1175             if (o == null) {
1176                 throw new NullPointerException("o == null");
1177             }
1178             return (String) o;
1179         }
1180     }
1181 }
1182