Home | History | Annotate | Download | only in vm
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 /*
     17  * Set up values for System.getProperties().
     18  */
     19 #include "Dalvik.h"
     20 
     21 #include <stdlib.h>
     22 #include <sys/utsname.h>
     23 #include <limits.h>
     24 #include <unistd.h>
     25 
     26 /*
     27  * Create some storage for properties read from the command line.
     28  */
     29 bool dvmPropertiesStartup(int maxProps)
     30 {
     31     gDvm.maxProps = maxProps;
     32     if (maxProps > 0) {
     33         gDvm.propList = (char**) malloc(maxProps * sizeof(char*));
     34         if (gDvm.propList == NULL)
     35             return false;
     36     }
     37     gDvm.numProps = 0;
     38 
     39     return true;
     40 }
     41 
     42 /*
     43  * Clean up.
     44  */
     45 void dvmPropertiesShutdown(void)
     46 {
     47     int i;
     48 
     49     for (i = 0; i < gDvm.numProps; i++)
     50         free(gDvm.propList[i]);
     51     free(gDvm.propList);
     52     gDvm.propList = NULL;
     53 }
     54 
     55 /*
     56  * Add a property specified on the command line.  "argStr" has the form
     57  * "name=value".  "name" must have nonzero length.
     58  *
     59  * Returns "true" if argStr appears valid.
     60  */
     61 bool dvmAddCommandLineProperty(const char* argStr)
     62 {
     63     char* mangle;
     64     char* equals;
     65 
     66     mangle = strdup(argStr);
     67     equals = strchr(mangle, '=');
     68     if (equals == NULL || equals == mangle) {
     69         free(mangle);
     70         return false;
     71     }
     72     *equals = '\0';
     73 
     74     assert(gDvm.numProps < gDvm.maxProps);
     75     gDvm.propList[gDvm.numProps++] = mangle;
     76 
     77     return true;
     78 }
     79 
     80 
     81 /*
     82  * Find the "put" method for this class.
     83  *
     84  * Returns NULL and throws an exception if not found.
     85  */
     86 static Method* getPut(ClassObject* clazz)
     87 {
     88     Method* put;
     89 
     90     put = dvmFindVirtualMethodHierByDescriptor(clazz, "setProperty",
     91             "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/Object;");
     92     if (put == NULL) {
     93         dvmThrowException("Ljava/lang/RuntimeException;",
     94             "could not find setProperty(String,String) in Properties");
     95         /* fall through to return */
     96     }
     97     return put;
     98 }
     99 
    100 /*
    101  * Set the value of the property.
    102  */
    103 static void setProperty(Object* propObj, Method* put, const char* key,
    104     const char* value)
    105 {
    106     StringObject* keyStr;
    107     StringObject* valueStr;
    108 
    109     if (value == NULL) {
    110         /* unclear what to do; probably want to create prop w/ empty string */
    111         value = "";
    112     }
    113 
    114     keyStr = dvmCreateStringFromCstr(key);
    115     valueStr = dvmCreateStringFromCstr(value);
    116     if (keyStr == NULL || valueStr == NULL) {
    117         LOGW("setProperty string creation failed\n");
    118         goto bail;
    119     }
    120 
    121     JValue unused;
    122     dvmCallMethod(dvmThreadSelf(), put, propObj, &unused, keyStr, valueStr);
    123 
    124 bail:
    125     dvmReleaseTrackedAlloc((Object*) keyStr, NULL);
    126     dvmReleaseTrackedAlloc((Object*) valueStr, NULL);
    127 }
    128 
    129 /*
    130  * Create the VM-default system properties.
    131  *
    132  * We can do them here, or do them in interpreted code with lots of native
    133  * methods to get bits and pieces.  This is a bit smaller.
    134  */
    135 void dvmCreateDefaultProperties(Object* propObj)
    136 {
    137     Method* put = getPut(propObj->clazz);
    138 
    139     if (put == NULL)
    140         return;
    141 
    142     struct utsname info;
    143     uname(&info);
    144 
    145     /* constant strings that are used multiple times below */
    146     const char *projectUrl = "http://www.android.com/";
    147     const char *projectName = "The Android Project";
    148 
    149     /*
    150      * These are listed in the docs.
    151      */
    152 
    153     setProperty(propObj, put, "java.boot.class.path", gDvm.bootClassPathStr);
    154     setProperty(propObj, put, "java.class.path", gDvm.classPathStr);
    155     setProperty(propObj, put, "java.class.version", "46.0");
    156     setProperty(propObj, put, "java.compiler", "");
    157     setProperty(propObj, put, "java.ext.dirs", "");
    158 
    159     if (getenv("JAVA_HOME") != NULL) {
    160         setProperty(propObj, put, "java.home", getenv("JAVA_HOME"));
    161     } else {
    162         setProperty(propObj, put, "java.home", "/system");
    163     }
    164 
    165     setProperty(propObj, put, "java.io.tmpdir", "/tmp");
    166     setProperty(propObj, put, "java.library.path", getenv("LD_LIBRARY_PATH"));
    167 
    168     setProperty(propObj, put, "java.net.preferIPv6Addresses", "true");
    169 
    170     setProperty(propObj, put, "java.vendor", projectName);
    171     setProperty(propObj, put, "java.vendor.url", projectUrl);
    172     setProperty(propObj, put, "java.version", "0");
    173     setProperty(propObj, put, "java.vm.name", "Dalvik");
    174     setProperty(propObj, put, "java.vm.specification.name",
    175             "Dalvik Virtual Machine Specification");
    176     setProperty(propObj, put, "java.vm.specification.vendor", projectName);
    177     setProperty(propObj, put, "java.vm.specification.version", "0.9");
    178     setProperty(propObj, put, "java.vm.vendor", projectName);
    179 
    180     char tmpBuf[64];
    181     sprintf(tmpBuf, "%d.%d.%d",
    182         DALVIK_MAJOR_VERSION, DALVIK_MINOR_VERSION, DALVIK_BUG_VERSION);
    183     setProperty(propObj, put, "java.vm.version", tmpBuf);
    184 
    185     setProperty(propObj, put, "java.specification.name",
    186             "Dalvik Core Library");
    187     setProperty(propObj, put, "java.specification.vendor", projectName);
    188     setProperty(propObj, put, "java.specification.version", "0.9");
    189 
    190     setProperty(propObj, put, "os.arch", info.machine);
    191     setProperty(propObj, put, "os.name", info.sysname);
    192     setProperty(propObj, put, "os.version", info.release);
    193     setProperty(propObj, put, "user.home", getenv("HOME"));
    194     setProperty(propObj, put, "user.name", getenv("USER"));
    195 
    196     char path[PATH_MAX];
    197     setProperty(propObj, put, "user.dir", getcwd(path, sizeof(path)));
    198 
    199     setProperty(propObj, put, "file.separator", "/");
    200     setProperty(propObj, put, "line.separator", "\n");
    201     setProperty(propObj, put, "path.separator", ":");
    202 
    203     /*
    204      * These show up elsewhere, so do them here too.
    205      */
    206     setProperty(propObj, put, "java.runtime.name", "Android Runtime");
    207     setProperty(propObj, put, "java.runtime.version", "0.9");
    208     setProperty(propObj, put, "java.vm.vendor.url", projectUrl);
    209 
    210     setProperty(propObj, put, "file.encoding", "UTF-8");
    211     setProperty(propObj, put, "user.language", "en");
    212     setProperty(propObj, put, "user.region", "US");
    213 
    214     /*
    215      * These are unique to Android/Dalvik.
    216      */
    217     setProperty(propObj, put, "android.vm.dexfile", "true");
    218 }
    219 
    220 /*
    221  * Add anything specified on the command line.
    222  */
    223 void dvmSetCommandLineProperties(Object* propObj)
    224 {
    225     Method* put = getPut(propObj->clazz);
    226     int i;
    227 
    228     if (put == NULL)
    229         return;
    230 
    231     for (i = 0; i < gDvm.numProps; i++) {
    232         const char* value;
    233 
    234         /* value starts after the end of the key string */
    235         for (value = gDvm.propList[i]; *value != '\0'; value++)
    236             ;
    237         setProperty(propObj, put, gDvm.propList[i], value+1);
    238     }
    239 }
    240 
    241 /*
    242  * Get a property by calling System.getProperty(key).
    243  *
    244  * Returns a newly-allocated string, or NULL on failure or key not found.
    245  * (Unexpected failures will also raise an exception.)
    246  */
    247 char* dvmGetProperty(const char* key)
    248 {
    249     ClassObject* system;
    250     Method* getProp;
    251     StringObject* keyObj = NULL;
    252     StringObject* valueObj;
    253     char* result = NULL;
    254 
    255     assert(key != NULL);
    256 
    257     system = dvmFindSystemClass("Ljava/lang/System;");
    258     if (system == NULL)
    259         goto bail;
    260 
    261     getProp = dvmFindDirectMethodByDescriptor(system, "getProperty",
    262         "(Ljava/lang/String;)Ljava/lang/String;");
    263     if (getProp == NULL) {
    264         LOGW("Could not find getProperty(String) in java.lang.System\n");
    265         goto bail;
    266     }
    267 
    268     keyObj = dvmCreateStringFromCstr(key);
    269     if (keyObj == NULL)
    270         goto bail;
    271 
    272     JValue val;
    273     dvmCallMethod(dvmThreadSelf(), getProp, NULL, &val, keyObj);
    274     valueObj = (StringObject*) val.l;
    275     if (valueObj == NULL)
    276         goto bail;
    277 
    278     result = dvmCreateCstrFromString(valueObj);
    279     /* fall through with result */
    280 
    281 bail:
    282     dvmReleaseTrackedAlloc((Object*)keyObj, NULL);
    283     return result;
    284 }
    285