• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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