System.java revision 16773d4f29a6cc3d0ab11f66ff15d606cffe4059
1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17/* 18 * Copyright (C) 2008 The Android Open Source Project 19 * 20 * Licensed under the Apache License, Version 2.0 (the "License"); 21 * you may not use this file except in compliance with the License. 22 * You may obtain a copy of the License at 23 * 24 * http://www.apache.org/licenses/LICENSE-2.0 25 * 26 * Unless required by applicable law or agreed to in writing, software 27 * distributed under the License is distributed on an "AS IS" BASIS, 28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 29 * See the License for the specific language governing permissions and 30 * limitations under the License. 31 */ 32 33package java.lang; 34 35import java.io.Console; 36import java.io.FileDescriptor; 37import java.io.FileInputStream; 38import java.io.FileOutputStream; 39import java.io.IOException; 40import java.io.InputStream; 41import java.io.PrintStream; 42import java.nio.channels.Channel; 43import java.nio.channels.spi.SelectorProvider; 44import java.security.SecurityPermission; 45import java.util.Collection; 46import java.util.HashMap; 47import java.util.Map; 48import java.util.Properties; 49import java.util.PropertyPermission; 50import java.util.Set; 51 52import dalvik.system.VMStack; 53 54/** 55 * Provides access to system-related information and resources including 56 * standard input and output. Enables clients to dynamically load native 57 * libraries. All methods of this class are accessed in a static way and the 58 * class itself can not be instantiated. 59 * 60 * @see Runtime 61 */ 62public final class System { 63 64 /** 65 * Default input stream. 66 */ 67 public static final InputStream in; 68 69 /** 70 * Default output stream. 71 */ 72 public static final PrintStream out; 73 74 /** 75 * Default error output stream. 76 */ 77 public static final PrintStream err; 78 79 /** 80 * The System Properties table. 81 */ 82 private static Properties systemProperties; 83 84 /** 85 * Initialize all the slots in System on first use. 86 */ 87 static { 88 /* 89 * Set up standard in, out, and err. TODO err and out are 90 * String.ConsolePrintStream. All three are buffered in Harmony. Check 91 * and possibly change this later. 92 */ 93 err = new PrintStream(new FileOutputStream(FileDescriptor.err)); 94 out = new PrintStream(new FileOutputStream(FileDescriptor.out)); 95 in = new FileInputStream(FileDescriptor.in); 96 } 97 98 /** 99 * Sets the standard input stream to the given user defined input stream. 100 * 101 * @param newIn 102 * the user defined input stream to set as the standard input 103 * stream. 104 * @throws SecurityException 105 * if a {@link SecurityManager} is installed and its {@code 106 * checkPermission()} method does not allow the change of the 107 * stream. 108 */ 109 public static void setIn(InputStream newIn) { 110 SecurityManager secMgr = System.getSecurityManager(); 111 if(secMgr != null) { 112 secMgr.checkPermission(RuntimePermission.permissionToSetIO); 113 } 114 setFieldImpl("in", "Ljava/io/InputStream;", newIn); 115 } 116 117 /** 118 * Sets the standard output stream to the given user defined output stream. 119 * 120 * @param newOut 121 * the user defined output stream to set as the standard output 122 * stream. 123 * @throws SecurityException 124 * if a {@link SecurityManager} is installed and its {@code 125 * checkPermission()} method does not allow the change of the 126 * stream. 127 */ 128 public static void setOut(java.io.PrintStream newOut) { 129 SecurityManager secMgr = System.getSecurityManager(); 130 if(secMgr != null) { 131 secMgr.checkPermission(RuntimePermission.permissionToSetIO); 132 } 133 setFieldImpl("out", "Ljava/io/PrintStream;", newOut); 134 } 135 136 /** 137 * Sets the standard error output stream to the given user defined output 138 * stream. 139 * 140 * @param newErr 141 * the user defined output stream to set as the standard error 142 * output stream. 143 * @throws SecurityException 144 * if a {@link SecurityManager} is installed and its {@code 145 * checkPermission()} method does not allow the change of the 146 * stream. 147 */ 148 public static void setErr(java.io.PrintStream newErr) { 149 SecurityManager secMgr = System.getSecurityManager(); 150 if(secMgr != null) { 151 secMgr.checkPermission(RuntimePermission.permissionToSetIO); 152 } 153 setFieldImpl("err", "Ljava/io/PrintStream;", newErr); 154 } 155 156 /** 157 * Prevents this class from being instantiated. 158 */ 159 private System() { 160 } 161 162 /** 163 * Copies {@code length} elements from the array {@code src}, 164 * starting at offset {@code srcPos}, into the array {@code dst}, 165 * starting at offset {@code dstPos}. 166 * 167 * @param src 168 * the source array to copy the content. 169 * @param srcPos 170 * the starting index of the content in {@code src}. 171 * @param dst 172 * the destination array to copy the data into. 173 * @param dstPos 174 * the starting index for the copied content in {@code dst}. 175 * @param length 176 * the number of elements to be copied. 177 */ 178 public static native void arraycopy(Object src, int srcPos, Object dst, int dstPos, int length); 179 180 /** 181 * Returns the current system time in milliseconds since January 1, 1970 182 * 00:00:00 UTC. This method shouldn't be used for measuring timeouts or 183 * other elapsed time measurements, as changing the system time can affect 184 * the results. 185 * 186 * @return the local system time in milliseconds. 187 */ 188 public static native long currentTimeMillis(); 189 190 /** 191 * Returns the current timestamp of the most precise timer available on the 192 * local system. This timestamp can only be used to measure an elapsed 193 * period by comparing it against another timestamp. It cannot be used as a 194 * very exact system time expression. 195 * 196 * @return the current timestamp in nanoseconds. 197 */ 198 public static native long nanoTime(); 199 200 /** 201 * Causes the virtual machine to stop running and the program to exit. If 202 * {@link #runFinalizersOnExit(boolean)} has been previously invoked with a 203 * {@code true} argument, then all objects will be properly 204 * garbage-collected and finalized first. 205 * 206 * @param code 207 * the return code. 208 * @throws SecurityException 209 * if the running thread has not enough permission to exit the 210 * virtual machine. 211 * @see SecurityManager#checkExit 212 */ 213 public static void exit(int code) { 214 Runtime.getRuntime().exit(code); 215 } 216 217 /** 218 * Indicates to the virtual machine that it would be a good time to run the 219 * garbage collector. Note that this is a hint only. There is no guarantee 220 * that the garbage collector will actually be run. 221 */ 222 public static void gc() { 223 Runtime.getRuntime().gc(); 224 } 225 226 /** 227 * Returns the value of the environment variable with the given name {@code 228 * var}. 229 * 230 * @param name 231 * the name of the environment variable. 232 * @return the value of the specified environment variable or {@code null} 233 * if no variable exists with the given name. 234 * @throws SecurityException 235 * if a {@link SecurityManager} is installed and its {@code 236 * checkPermission()} method does not allow the querying of 237 * single environment variables. 238 */ 239 public static String getenv(String name) { 240 if (name == null) { 241 throw new NullPointerException(); 242 } 243 SecurityManager secMgr = System.getSecurityManager(); 244 if (secMgr != null) { 245 secMgr.checkPermission(new RuntimePermission("getenv." + name)); 246 } 247 248 return getEnvByName(name); 249 } 250 251 /* 252 * Returns an environment variable. No security checks are performed. 253 * @param var the name of the environment variable 254 * @return the value of the specified environment variable 255 */ 256 private static native String getEnvByName(String name); 257 258 /** 259 * Returns an unmodifiable map of all available environment variables. 260 * 261 * @return the map representing all environment variables. 262 * @throws SecurityException 263 * if a {@link SecurityManager} is installed and its {@code 264 * checkPermission()} method does not allow the querying of 265 * all environment variables. 266 */ 267 public static Map<String, String> getenv() { 268 SecurityManager secMgr = System.getSecurityManager(); 269 if (secMgr != null) { 270 secMgr.checkPermission(new RuntimePermission("getenv.*")); 271 } 272 273 Map<String, String> map = new HashMap<String, String>(); 274 275 int index = 0; 276 String entry = getEnvByIndex(index++); 277 while (entry != null) { 278 int pos = entry.indexOf('='); 279 if (pos != -1) { 280 map.put(entry.substring(0, pos), entry.substring(pos + 1)); 281 } 282 283 entry = getEnvByIndex(index++); 284 } 285 286 return new SystemEnvironment(map); 287 } 288 289 /* 290 * Returns an environment variable. No security checks are performed. The 291 * safe way of traversing the environment is to start at index zero and 292 * count upwards until a null pointer is encountered. This marks the end of 293 * the Unix environment. 294 * @param index the index of the environment variable 295 * @return the value of the specified environment variable 296 */ 297 private static native String getEnvByIndex(int index); 298 299 /** 300 * Returns the inherited channel from the creator of the current virtual 301 * machine. 302 * 303 * @return the inherited {@link Channel} or {@code null} if none exists. 304 * @throws IOException 305 * if an I/O error occurred. 306 * @see SelectorProvider 307 * @see SelectorProvider#inheritedChannel() 308 */ 309 public static Channel inheritedChannel() throws IOException { 310 return SelectorProvider.provider().inheritedChannel(); 311 } 312 313 /** 314 * Returns the system properties. Note that this is not a copy, so that 315 * changes made to the returned Properties object will be reflected in 316 * subsequent calls to getProperty and getProperties. 317 * 318 * @return the system properties. 319 * @throws SecurityException 320 * if a {@link SecurityManager} is installed and its {@code 321 * checkPropertiesAccess()} method does not allow the operation. 322 */ 323 public static Properties getProperties() { 324 SecurityManager secMgr = System.getSecurityManager(); 325 if (secMgr != null) { 326 secMgr.checkPropertiesAccess(); 327 } 328 329 return internalGetProperties(); 330 } 331 332 /** 333 * Returns the system properties without any security checks. This is used 334 * for access from within java.lang. 335 * 336 * @return the system properties 337 */ 338 static Properties internalGetProperties() { 339 if (System.systemProperties == null) { 340 SystemProperties props = new SystemProperties(); 341 props.preInit(); 342 props.postInit(); 343 System.systemProperties = props; 344 } 345 346 return systemProperties; 347 } 348 349 /** 350 * Returns the value of a particular system property or {@code null} if no 351 * such property exists. 352 * 353 * <p>The following properties are always provided by the virtual machine: 354 * <p><table BORDER="1" WIDTH="100%" CELLPADDING="3" CELLSPACING="0" SUMMARY=""> 355 * <tr BGCOLOR="#CCCCFF" CLASS="TableHeadingColor"> 356 * <td><b>Name</b></td> <td><b>Meaning</b></td> <td><b>Example</b></td></tr> 357 * <tr><td>file.separator</td> <td>{@link java.io.File#separator}</td> <td>{@code /}</td></tr> 358 * 359 * <tr><td>java.class.path</td> <td>System class path</td> <td>{@code .}</td></tr> 360 * <tr><td>java.class.version</td> <td>Maximum supported .class file version</td> <td>{@code 46.0}</td></tr> 361 * <tr><td>java.compiler</td> <td>(Not useful on Android)</td> <td>Empty</td></tr> 362 * <tr><td>java.ext.dirs</td> <td>(Not useful on Android)</td> <td>Empty</td></tr> 363 * <tr><td>java.home</td> <td>Location of the VM on the file system</td> <td>{@code /system}</td></tr> 364 * <tr><td>java.io.tmpdir</td> <td>See {@link java.io.File#createTempFile}</td> <td>{@code /sdcard}</td></tr> 365 * <tr><td>java.library.path</td> <td>Search path for JNI libraries</td> <td>{@code /system/lib}</td></tr> 366 * <tr><td>java.vendor</td> <td>Human-readable VM vendor</td> <td>{@code The Android Project}</td></tr> 367 * <tr><td>java.vendor.url</td> <td>URL for VM vendor's web site</td> <td>{@code http://www.android.com/}</td></tr> 368 * <tr><td>java.version</td> <td>(Not useful on Android)</td> <td>{@code 0}</td></tr> 369 * 370 * <tr><td>java.specification.version</td> <td>VM libraries version</td> <td>{@code 0.9}</td></tr> 371 * <tr><td>java.specification.vendor</td> <td>VM libraries vendor</td> <td>{@code The Android Project}</td></tr> 372 * <tr><td>java.specification.name</td> <td>VM libraries name</td> <td>{@code Dalvik Core Library}</td></tr> 373 * <tr><td>java.vm.version</td> <td>VM implementation version</td> <td>{@code 1.2.0}</td></tr> 374 * <tr><td>java.vm.vendor</td> <td>VM implementation vendor</td> <td>{@code The Android Project}</td></tr> 375 * <tr><td>java.vm.name</td> <td>VM implementation name</td> <td>{@code Dalvik}</td></tr> 376 * <tr><td>java.vm.specification.version</td> <td>VM specification version</td> <td>{@code 0.9}</td></tr> 377 * <tr><td>java.vm.specification.vendor</td> <td>VM specification vendor</td> <td>{@code The Android Project}</td></tr> 378 * <tr><td>java.vm.specification.name</td> <td>VM specification name</td> <td>{@code Dalvik Virtual Machine Specification}</td></tr> 379 * 380 * <tr><td>line.separator</td> <td>Default line separator</td> <td>{@code \n}</td></tr> 381 * 382 * <tr><td>os.arch</td> <td>OS architecture</td> <td>{@code armv7l}</td></tr> 383 * <tr><td>os.name</td> <td>OS (kernel) name</td> <td>{@code Linux}</td></tr> 384 * <tr><td>os.version</td> <td>OS (kernel) version</td> <td>{@code 2.6.32.9-g103d848}</td></tr> 385 * 386 * <tr><td>path.separator</td> <td>{@link java.io.File#pathSeparator}</td> <td>{@code :}</td></tr> 387 * 388 * <tr><td>user.dir</td> <td>Base of non-absolute paths</td> <td>{@code /}</td></tr> 389 * <tr><td>user.home</td> <td>(Not useful on Android)</td> <td>Empty</td></tr> 390 * <tr><td>user.name</td> <td>(Not useful on Android)</td> <td>Empty</td></tr> 391 * 392 * </table> 393 * 394 * @param propertyName 395 * the name of the system property to look up. 396 * @return the value of the specified system property or {@code null} if the 397 * property doesn't exist. 398 * @throws SecurityException 399 * if a {@link SecurityManager} is installed and its {@code 400 * checkPropertyAccess()} method does not allow the operation. 401 */ 402 public static String getProperty(String propertyName) { 403 return getProperty(propertyName, null); 404 } 405 406 /** 407 * Returns the value of a particular system property. The {@code 408 * defaultValue} will be returned if no such property has been found. 409 * 410 * @param prop 411 * the name of the system property to look up. 412 * @param defaultValue 413 * the return value if the system property with the given name 414 * does not exist. 415 * @return the value of the specified system property or the {@code 416 * defaultValue} if the property does not exist. 417 * @throws SecurityException 418 * if a {@link SecurityManager} is installed and its {@code 419 * checkPropertyAccess()} method does not allow the operation. 420 */ 421 public static String getProperty(String prop, String defaultValue) { 422 if (prop.length() == 0) { 423 throw new IllegalArgumentException(); 424 } 425 SecurityManager secMgr = System.getSecurityManager(); 426 if (secMgr != null) { 427 secMgr.checkPropertyAccess(prop); 428 } 429 430 return internalGetProperties().getProperty(prop, defaultValue); 431 } 432 433 /** 434 * Sets the value of a particular system property. 435 * 436 * @param prop 437 * the name of the system property to be changed. 438 * @param value 439 * the value to associate with the given property {@code prop}. 440 * @return the old value of the property or {@code null} if the property 441 * didn't exist. 442 * @throws SecurityException 443 * if a security manager exists and write access to the 444 * specified property is not allowed. 445 */ 446 public static String setProperty(String prop, String value) { 447 if (prop.length() == 0) { 448 throw new IllegalArgumentException(); 449 } 450 SecurityManager secMgr = System.getSecurityManager(); 451 if (secMgr != null) { 452 secMgr.checkPermission(new PropertyPermission(prop, "write")); 453 } 454 return (String)internalGetProperties().setProperty(prop, value); 455 } 456 457 /** 458 * Removes a specific system property. 459 * 460 * @param key 461 * the name of the system property to be removed. 462 * @return the property value or {@code null} if the property didn't exist. 463 * @throws NullPointerException 464 * if the argument {@code key} is {@code null}. 465 * @throws IllegalArgumentException 466 * if the argument {@code key} is empty. 467 * @throws SecurityException 468 * if a security manager exists and write access to the 469 * specified property is not allowed. 470 */ 471 public static String clearProperty(String key) { 472 if (key == null) { 473 throw new NullPointerException(); 474 } 475 if (key.length() == 0) { 476 throw new IllegalArgumentException(); 477 } 478 479 SecurityManager secMgr = System.getSecurityManager(); 480 if (secMgr != null) { 481 secMgr.checkPermission(new PropertyPermission(key, "write")); 482 } 483 return (String)internalGetProperties().remove(key); 484 } 485 486 /** 487 * Returns the {@link java.io.Console} associated with this VM, or null. 488 * Not all VMs will have an associated console. A console is typically only 489 * available for programs run from the command line. 490 * @since 1.6 491 */ 492 public static Console console() { 493 return Console.getConsole(); 494 } 495 496 /** 497 * Returns null. Android does not use {@code SecurityManager}. This method 498 * is only provided for source compatibility. 499 * 500 * @return null 501 */ 502 public static SecurityManager getSecurityManager() { 503 return null; 504 } 505 506 /** 507 * Returns an integer hash code for the parameter. The hash code returned is 508 * the same one that would be returned by the method {@code 509 * java.lang.Object.hashCode()}, whether or not the object's class has 510 * overridden hashCode(). The hash code for {@code null} is {@code 0}. 511 * 512 * @param anObject 513 * the object to calculate the hash code. 514 * @return the hash code for the given object. 515 * @see java.lang.Object#hashCode 516 */ 517 public static native int identityHashCode(Object anObject); 518 519 /** 520 * Loads the specified file as a dynamic library. 521 * 522 * @param pathName 523 * the path of the file to be loaded. 524 * @throws SecurityException 525 * if the library was not allowed to be loaded. 526 */ 527 public static void load(String pathName) { 528 SecurityManager smngr = System.getSecurityManager(); 529 if (smngr != null) { 530 smngr.checkLink(pathName); 531 } 532 Runtime.getRuntime().load(pathName, VMStack.getCallingClassLoader()); 533 } 534 535 /** 536 * Loads and links the shared library with the given name {@code libName}. 537 * The file will be searched in the default directory for shared libraries 538 * of the local system. 539 * 540 * @param libName 541 * the name of the library to load. 542 * @throws UnsatisfiedLinkError 543 * if the library could not be loaded. 544 * @throws SecurityException 545 * if the library was not allowed to be loaded. 546 */ 547 public static void loadLibrary(String libName) { 548 SecurityManager smngr = System.getSecurityManager(); 549 if (smngr != null) { 550 smngr.checkLink(libName); 551 } 552 Runtime.getRuntime().loadLibrary(libName, VMStack.getCallingClassLoader()); 553 } 554 555 /** 556 * Provides a hint to the virtual machine that it would be useful to attempt 557 * to perform any outstanding object finalization. 558 */ 559 public static void runFinalization() { 560 Runtime.getRuntime().runFinalization(); 561 } 562 563 /** 564 * Ensures that, when the virtual machine is about to exit, all objects are 565 * finalized. Note that all finalization which occurs when the system is 566 * exiting is performed after all running threads have been terminated. 567 * 568 * @param flag 569 * the flag determines if finalization on exit is enabled. 570 * @deprecated this method is unsafe. 571 */ 572 @SuppressWarnings("deprecation") 573 @Deprecated 574 public static void runFinalizersOnExit(boolean flag) { 575 Runtime.runFinalizersOnExit(flag); 576 } 577 578 /** 579 * Sets all system properties. 580 * 581 * @param p 582 * the new system property. 583 * @throws SecurityException 584 * if a {@link SecurityManager} is installed and its {@code 585 * checkPropertiesAccess()} method does not allow the operation. 586 */ 587 public static void setProperties(Properties p) { 588 SecurityManager secMgr = System.getSecurityManager(); 589 if (secMgr != null) { 590 secMgr.checkPropertiesAccess(); 591 } 592 593 systemProperties = p; 594 } 595 596 /** 597 * Throws {@code SecurityException}. 598 * 599 * <p>Security managers do <i>not</i> provide a secure environment for 600 * executing untrusted code and are unsupported on Android. Untrusted code 601 * cannot be safely isolated within a single VM on Android. 602 * 603 * @param sm a security manager 604 * @throws SecurityException always 605 */ 606 public static void setSecurityManager(SecurityManager sm) { 607 if (sm != null) { 608 throw new SecurityException(); 609 } 610 } 611 612 /** 613 * Returns the platform specific file name format for the shared library 614 * named by the argument. 615 * 616 * @param userLibName 617 * the name of the library to look up. 618 * @return the platform specific filename for the library. 619 */ 620 public static native String mapLibraryName(String userLibName); 621 622 /** 623 * Sets the value of the named static field in the receiver to the passed in 624 * argument. 625 * 626 * @param fieldName 627 * the name of the field to set, one of in, out, or err 628 * @param stream 629 * the new value of the field 630 */ 631 private static native void setFieldImpl(String fieldName, String signature, Object stream); 632 633} 634 635/** 636 * Internal class holding the System properties. Needed by the Dalvik VM for the 637 * two native methods. Must not be a local class, since we don't have a System 638 * instance. 639 */ 640class SystemProperties extends Properties { 641 // Dummy, just to make the compiler happy. 642 643 native void preInit(); 644 645 native void postInit(); 646} 647 648/** 649 * Internal class holding the System environment variables. The Java spec 650 * mandates that this map be read-only, so we wrap our real map into this one 651 * and make sure no one touches the contents. We also check for null parameters 652 * and do some (seemingly unnecessary) type casts to fulfill the contract layed 653 * out in the spec. 654 */ 655class SystemEnvironment implements Map { 656 657 private Map<String, String> map; 658 659 public SystemEnvironment(Map<String, String> map) { 660 this.map = map; 661 } 662 663 public void clear() { 664 throw new UnsupportedOperationException("Can't modify environment"); 665 } 666 667 @SuppressWarnings("cast") 668 public boolean containsKey(Object key) { 669 if (key == null) { 670 throw new NullPointerException(); 671 } 672 673 return map.containsKey((String)key); 674 } 675 676 @SuppressWarnings("cast") 677 public boolean containsValue(Object value) { 678 if (value == null) { 679 throw new NullPointerException(); 680 } 681 682 return map.containsValue((String)value); 683 } 684 685 public Set entrySet() { 686 return map.entrySet(); 687 } 688 689 @SuppressWarnings("cast") 690 public String get(Object key) { 691 if (key == null) { 692 throw new NullPointerException(); 693 } 694 695 return map.get((String)key); 696 } 697 698 public boolean isEmpty() { 699 return map.isEmpty(); 700 } 701 702 public Set<String> keySet() { 703 return map.keySet(); 704 } 705 706 public String put(Object key, Object value) { 707 throw new UnsupportedOperationException("Can't modify environment"); 708 } 709 710 public void putAll(Map map) { 711 throw new UnsupportedOperationException("Can't modify environment"); 712 } 713 714 public String remove(Object key) { 715 throw new UnsupportedOperationException("Can't modify environment"); 716 } 717 718 public int size() { 719 return map.size(); 720 } 721 722 public Collection values() { 723 return map.values(); 724 } 725 726} 727