System.java revision ccbe3404e0691dab506d017550658e8e5974c83e
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 * <p> 353 * The properties currently provided by the virtual machine are: 354 * 355 * <pre> 356 * java.vendor.url 357 * java.class.path 358 * user.home 359 * java.class.version 360 * os.version 361 * java.vendor 362 * user.dir 363 * user.timezone 364 * path.separator 365 * os.name 366 * os.arch 367 * line.separator 368 * file.separator 369 * user.name 370 * java.version 371 * java.home 372 * </pre> 373 * 374 * @param prop 375 * the name of the system property to look up. 376 * @return the value of the specified system property or {@code null} if the 377 * property doesn't exist. 378 * @throws SecurityException 379 * if a {@link SecurityManager} is installed and its {@code 380 * checkPropertyAccess()} method does not allow the operation. 381 */ 382 public static String getProperty(String prop) { 383 return getProperty(prop, null); 384 } 385 386 /** 387 * Returns the value of a particular system property. The {@code 388 * defaultValue} will be returned if no such property has been found. 389 * 390 * @param prop 391 * the name of the system property to look up. 392 * @param defaultValue 393 * the return value if the system property with the given name 394 * does not exist. 395 * @return the value of the specified system property or the {@code 396 * defaultValue} if the property does not exist. 397 * @throws SecurityException 398 * if a {@link SecurityManager} is installed and its {@code 399 * checkPropertyAccess()} method does not allow the operation. 400 */ 401 public static String getProperty(String prop, String defaultValue) { 402 if (prop.length() == 0) { 403 throw new IllegalArgumentException(); 404 } 405 SecurityManager secMgr = System.getSecurityManager(); 406 if (secMgr != null) { 407 secMgr.checkPropertyAccess(prop); 408 } 409 410 return internalGetProperties().getProperty(prop, defaultValue); 411 } 412 413 /** 414 * Sets the value of a particular system property. 415 * 416 * @param prop 417 * the name of the system property to be changed. 418 * @param value 419 * the value to associate with the given property {@code prop}. 420 * @return the old value of the property or {@code null} if the property 421 * didn't exist. 422 * @throws SecurityException 423 * if a security manager exists and write access to the 424 * specified property is not allowed. 425 */ 426 public static String setProperty(String prop, String value) { 427 if (prop.length() == 0) { 428 throw new IllegalArgumentException(); 429 } 430 SecurityManager secMgr = System.getSecurityManager(); 431 if (secMgr != null) { 432 secMgr.checkPermission(new PropertyPermission(prop, "write")); 433 } 434 return (String)internalGetProperties().setProperty(prop, value); 435 } 436 437 /** 438 * Removes a specific system property. 439 * 440 * @param key 441 * the name of the system property to be removed. 442 * @return the property value or {@code null} if the property didn't exist. 443 * @throws NullPointerException 444 * if the argument {@code key} is {@code null}. 445 * @throws IllegalArgumentException 446 * if the argument {@code key} is empty. 447 * @throws SecurityException 448 * if a security manager exists and write access to the 449 * specified property is not allowed. 450 */ 451 public static String clearProperty(String key) { 452 if (key == null) { 453 throw new NullPointerException(); 454 } 455 if (key.length() == 0) { 456 throw new IllegalArgumentException(); 457 } 458 459 SecurityManager secMgr = System.getSecurityManager(); 460 if (secMgr != null) { 461 secMgr.checkPermission(new PropertyPermission(key, "write")); 462 } 463 return (String)internalGetProperties().remove(key); 464 } 465 466 /** 467 * Returns the {@link java.io.Console} associated with this VM, or null. 468 * Not all VMs will have an associated console. A console is typically only 469 * available for programs run from the command line. 470 * @since 1.6 471 */ 472 public static Console console() { 473 return Console.getConsole(); 474 } 475 476 /** 477 * Returns null. Android does not use {@code SecurityManager}. This method 478 * is only provided for source compatibility. 479 * 480 * @return null 481 */ 482 public static SecurityManager getSecurityManager() { 483 return null; 484 } 485 486 /** 487 * Returns an integer hash code for the parameter. The hash code returned is 488 * the same one that would be returned by the method {@code 489 * java.lang.Object.hashCode()}, whether or not the object's class has 490 * overridden hashCode(). The hash code for {@code null} is {@code 0}. 491 * 492 * @param anObject 493 * the object to calculate the hash code. 494 * @return the hash code for the given object. 495 * @see java.lang.Object#hashCode 496 */ 497 public static native int identityHashCode(Object anObject); 498 499 /** 500 * Loads the specified file as a dynamic library. 501 * 502 * @param pathName 503 * the path of the file to be loaded. 504 * @throws SecurityException 505 * if the library was not allowed to be loaded. 506 */ 507 public static void load(String pathName) { 508 SecurityManager smngr = System.getSecurityManager(); 509 if (smngr != null) { 510 smngr.checkLink(pathName); 511 } 512 Runtime.getRuntime().load(pathName, VMStack.getCallingClassLoader()); 513 } 514 515 /** 516 * Loads and links the shared library with the given name {@code libName}. 517 * The file will be searched in the default directory for shared libraries 518 * of the local system. 519 * 520 * @param libName 521 * the name of the library to load. 522 * @throws UnsatisfiedLinkError 523 * if the library could not be loaded. 524 * @throws SecurityException 525 * if the library was not allowed to be loaded. 526 */ 527 public static void loadLibrary(String libName) { 528 SecurityManager smngr = System.getSecurityManager(); 529 if (smngr != null) { 530 smngr.checkLink(libName); 531 } 532 Runtime.getRuntime().loadLibrary(libName, VMStack.getCallingClassLoader()); 533 } 534 535 /** 536 * Provides a hint to the virtual machine that it would be useful to attempt 537 * to perform any outstanding object finalization. 538 */ 539 public static void runFinalization() { 540 Runtime.getRuntime().runFinalization(); 541 } 542 543 /** 544 * Ensures that, when the virtual machine is about to exit, all objects are 545 * finalized. Note that all finalization which occurs when the system is 546 * exiting is performed after all running threads have been terminated. 547 * 548 * @param flag 549 * the flag determines if finalization on exit is enabled. 550 * @deprecated this method is unsafe. 551 */ 552 @SuppressWarnings("deprecation") 553 @Deprecated 554 public static void runFinalizersOnExit(boolean flag) { 555 Runtime.runFinalizersOnExit(flag); 556 } 557 558 /** 559 * Sets all system properties. 560 * 561 * @param p 562 * the new system property. 563 * @throws SecurityException 564 * if a {@link SecurityManager} is installed and its {@code 565 * checkPropertiesAccess()} method does not allow the operation. 566 */ 567 public static void setProperties(Properties p) { 568 SecurityManager secMgr = System.getSecurityManager(); 569 if (secMgr != null) { 570 secMgr.checkPropertiesAccess(); 571 } 572 573 systemProperties = p; 574 } 575 576 /** 577 * Throws {@code SecurityException}. 578 * 579 * <p>Security managers do <i>not</i> provide a secure environment for 580 * executing untrusted code and are unsupported on Android. Untrusted code 581 * cannot be safely isolated within a single VM on Android. 582 * 583 * @param sm a security manager 584 * @throws SecurityException always 585 */ 586 public static void setSecurityManager(SecurityManager sm) { 587 if (sm != null) { 588 throw new SecurityException(); 589 } 590 } 591 592 /** 593 * Returns the platform specific file name format for the shared library 594 * named by the argument. 595 * 596 * @param userLibName 597 * the name of the library to look up. 598 * @return the platform specific filename for the library. 599 */ 600 public static native String mapLibraryName(String userLibName); 601 602 /** 603 * Sets the value of the named static field in the receiver to the passed in 604 * argument. 605 * 606 * @param fieldName 607 * the name of the field to set, one of in, out, or err 608 * @param stream 609 * the new value of the field 610 */ 611 private static native void setFieldImpl(String fieldName, String signature, Object stream); 612 613} 614 615/** 616 * Internal class holding the System properties. Needed by the Dalvik VM for the 617 * two native methods. Must not be a local class, since we don't have a System 618 * instance. 619 */ 620class SystemProperties extends Properties { 621 // Dummy, just to make the compiler happy. 622 623 native void preInit(); 624 625 native void postInit(); 626} 627 628/** 629 * Internal class holding the System environment variables. The Java spec 630 * mandates that this map be read-only, so we wrap our real map into this one 631 * and make sure no one touches the contents. We also check for null parameters 632 * and do some (seemingly unnecessary) type casts to fulfill the contract layed 633 * out in the spec. 634 */ 635class SystemEnvironment implements Map { 636 637 private Map<String, String> map; 638 639 public SystemEnvironment(Map<String, String> map) { 640 this.map = map; 641 } 642 643 public void clear() { 644 throw new UnsupportedOperationException("Can't modify environment"); 645 } 646 647 @SuppressWarnings("cast") 648 public boolean containsKey(Object key) { 649 if (key == null) { 650 throw new NullPointerException(); 651 } 652 653 return map.containsKey((String)key); 654 } 655 656 @SuppressWarnings("cast") 657 public boolean containsValue(Object value) { 658 if (value == null) { 659 throw new NullPointerException(); 660 } 661 662 return map.containsValue((String)value); 663 } 664 665 public Set entrySet() { 666 return map.entrySet(); 667 } 668 669 @SuppressWarnings("cast") 670 public String get(Object key) { 671 if (key == null) { 672 throw new NullPointerException(); 673 } 674 675 return map.get((String)key); 676 } 677 678 public boolean isEmpty() { 679 return map.isEmpty(); 680 } 681 682 public Set<String> keySet() { 683 return map.keySet(); 684 } 685 686 public String put(Object key, Object value) { 687 throw new UnsupportedOperationException("Can't modify environment"); 688 } 689 690 public void putAll(Map map) { 691 throw new UnsupportedOperationException("Can't modify environment"); 692 } 693 694 public String remove(Object key) { 695 throw new UnsupportedOperationException("Can't modify environment"); 696 } 697 698 public int size() { 699 return map.size(); 700 } 701 702 public Collection values() { 703 return map.values(); 704 } 705 706} 707