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