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