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