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