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