Home | History | Annotate | Download | only in android
      1 /* Copyright (C) 2011 The Android Open Source Project
      2 **
      3 ** This software is licensed under the terms of the GNU General Public
      4 ** License version 2, as published by the Free Software Foundation, and
      5 ** may be copied, distributed, and modified under those terms.
      6 **
      7 ** This program is distributed in the hope that it will be useful,
      8 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
      9 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     10 ** GNU General Public License for more details.
     11 */
     12 #include <signal.h>
     13 #include <unistd.h>
     14 #include <string.h>
     15 #include <sys/time.h>
     16 #include <errno.h>
     17 #include <fcntl.h>
     18 #ifdef _WIN32
     19 #include <process.h>
     20 #endif
     21 
     22 #include <SDL.h>
     23 #include <SDL_syswm.h>
     24 
     25 #include "console.h"
     26 
     27 #include "android/utils/debug.h"
     28 #include "android/utils/path.h"
     29 #include "android/utils/bufprint.h"
     30 #include "android/utils/dirscanner.h"
     31 #include "android/main-common.h"
     32 #include "android/globals.h"
     33 #include "android/resource.h"
     34 #include "android/user-config.h"
     35 #include "android/qemulator.h"
     36 #include "android/display.h"
     37 #include "android/skin/image.h"
     38 #include "android/skin/trackball.h"
     39 #include "android/skin/keyboard.h"
     40 #include "android/skin/file.h"
     41 #include "android/skin/window.h"
     42 
     43 
     44 
     45 /***********************************************************************/
     46 /***********************************************************************/
     47 /*****                                                             *****/
     48 /*****            U T I L I T Y   R O U T I N E S                  *****/
     49 /*****                                                             *****/
     50 /***********************************************************************/
     51 /***********************************************************************/
     52 
     53 #define  D(...)  do {  if (VERBOSE_CHECK(init)) dprint(__VA_ARGS__); } while (0)
     54 
     55 /***  CONFIGURATION
     56  ***/
     57 
     58 static AUserConfig*  userConfig;
     59 
     60 void
     61 user_config_init( void )
     62 {
     63     userConfig = auserConfig_new( android_avdInfo );
     64 }
     65 
     66 /* only call this function on normal exits, so that ^C doesn't save the configuration */
     67 void
     68 user_config_done( void )
     69 {
     70     int  win_x, win_y;
     71 
     72     if (!userConfig) {
     73         D("no user configuration?");
     74         return;
     75     }
     76 
     77     SDL_WM_GetPos( &win_x, &win_y );
     78     auserConfig_setWindowPos(userConfig, win_x, win_y);
     79     auserConfig_save(userConfig);
     80 }
     81 
     82 void
     83 user_config_get_window_pos( int *window_x, int *window_y )
     84 {
     85     *window_x = *window_y = 10;
     86 
     87     if (userConfig)
     88         auserConfig_getWindowPos(userConfig, window_x, window_y);
     89 }
     90 
     91 unsigned convertBytesToMB( uint64_t  size )
     92 {
     93     if (size == 0)
     94         return 0;
     95 
     96     size = (size + ONE_MB-1) >> 20;
     97     if (size > UINT_MAX)
     98         size = UINT_MAX;
     99 
    100     return (unsigned) size;
    101 }
    102 
    103 uint64_t convertMBToBytes( unsigned  megaBytes )
    104 {
    105     return ((uint64_t)megaBytes << 20);
    106 }
    107 
    108 
    109 /***********************************************************************/
    110 /***********************************************************************/
    111 /*****                                                             *****/
    112 /*****            K E Y S E T   R O U T I N E S                    *****/
    113 /*****                                                             *****/
    114 /***********************************************************************/
    115 /***********************************************************************/
    116 
    117 #define  KEYSET_FILE    "default.keyset"
    118 
    119 SkinKeyset*  android_keyset = NULL;
    120 
    121 static int
    122 load_keyset(const char*  path)
    123 {
    124     if (path_can_read(path)) {
    125         AConfig*  root = aconfig_node("","");
    126         if (!aconfig_load_file(root, path)) {
    127             android_keyset = skin_keyset_new(root);
    128             if (android_keyset != NULL) {
    129                 D( "keyset loaded from: %s", path);
    130                 return 0;
    131             }
    132         }
    133     }
    134     return -1;
    135 }
    136 
    137 void
    138 parse_keyset(const char*  keyset, AndroidOptions*  opts)
    139 {
    140     char   kname[MAX_PATH];
    141     char   temp[MAX_PATH];
    142     char*  p;
    143     char*  end;
    144 
    145     /* append .keyset suffix if needed */
    146     if (strchr(keyset, '.') == NULL) {
    147         p   =  kname;
    148         end = p + sizeof(kname);
    149         p   = bufprint(p, end, "%s.keyset", keyset);
    150         if (p >= end) {
    151             derror( "keyset name too long: '%s'\n", keyset);
    152             exit(1);
    153         }
    154         keyset = kname;
    155     }
    156 
    157     /* look for a the keyset file */
    158     p   = temp;
    159     end = p + sizeof(temp);
    160     p = bufprint_config_file(p, end, keyset);
    161     if (p < end && load_keyset(temp) == 0)
    162         return;
    163 
    164     p = temp;
    165     p = bufprint(p, end, "%s" PATH_SEP "keysets" PATH_SEP "%s", opts->sysdir, keyset);
    166     if (p < end && load_keyset(temp) == 0)
    167         return;
    168 
    169     p = temp;
    170     p = bufprint_app_dir(p, end);
    171     p = bufprint(p, end, PATH_SEP "keysets" PATH_SEP "%s", keyset);
    172     if (p < end && load_keyset(temp) == 0)
    173         return;
    174 
    175     return;
    176 }
    177 
    178 void
    179 write_default_keyset( void )
    180 {
    181     char   path[MAX_PATH];
    182 
    183     bufprint_config_file( path, path+sizeof(path), KEYSET_FILE );
    184 
    185     /* only write if there is no file here */
    186     if ( !path_exists(path) ) {
    187         int          fd = open( path, O_WRONLY | O_CREAT, 0666 );
    188         int          ret;
    189         const char*  ks = skin_keyset_get_default();
    190 
    191 
    192         D( "writing default keyset file to %s", path );
    193 
    194         if (fd < 0) {
    195             D( "%s: could not create file: %s", __FUNCTION__, strerror(errno) );
    196             return;
    197         }
    198         CHECKED(ret, write(fd, ks, strlen(ks)));
    199         close(fd);
    200     }
    201 }
    202 
    203 
    204 
    205 /***********************************************************************/
    206 /***********************************************************************/
    207 /*****                                                             *****/
    208 /*****            S D L   S U P P O R T                            *****/
    209 /*****                                                             *****/
    210 /***********************************************************************/
    211 /***********************************************************************/
    212 
    213 void *readpng(const unsigned char*  base, size_t  size, unsigned *_width, unsigned *_height);
    214 
    215 #ifdef CONFIG_DARWIN
    216 #  define  ANDROID_ICON_PNG  "android_icon_256.png"
    217 #else
    218 #  define  ANDROID_ICON_PNG  "android_icon_16.png"
    219 #endif
    220 
    221 static void
    222 sdl_set_window_icon( void )
    223 {
    224     static int  window_icon_set;
    225 
    226     if (!window_icon_set)
    227     {
    228 #ifdef _WIN32
    229         HANDLE         handle = GetModuleHandle( NULL );
    230         HICON          icon   = LoadIcon( handle, MAKEINTRESOURCE(1) );
    231         SDL_SysWMinfo  wminfo;
    232 
    233         SDL_GetWMInfo(&wminfo);
    234 
    235         SetClassLong( wminfo.window, GCL_HICON, (LONG)icon );
    236 #else  /* !_WIN32 */
    237         unsigned              icon_w, icon_h;
    238         size_t                icon_bytes;
    239         const unsigned char*  icon_data;
    240         void*                 icon_pixels;
    241 
    242         window_icon_set = 1;
    243 
    244         icon_data = android_icon_find( ANDROID_ICON_PNG, &icon_bytes );
    245         if ( !icon_data )
    246             return;
    247 
    248         icon_pixels = readpng( icon_data, icon_bytes, &icon_w, &icon_h );
    249         if ( !icon_pixels )
    250             return;
    251 
    252        /* the data is loaded into memory as RGBA bytes by libpng. we want to manage
    253         * the values as 32-bit ARGB pixels, so swap the bytes accordingly depending
    254         * on our CPU endianess
    255         */
    256         {
    257             unsigned*  d     = icon_pixels;
    258             unsigned*  d_end = d + icon_w*icon_h;
    259 
    260             for ( ; d < d_end; d++ ) {
    261                 unsigned  pix = d[0];
    262 #if HOST_WORDS_BIGENDIAN
    263                 /* R,G,B,A read as RGBA => ARGB */
    264                 pix = ((pix >> 8) & 0xffffff) | (pix << 24);
    265 #else
    266                 /* R,G,B,A read as ABGR => ARGB */
    267                 pix = (pix & 0xff00ff00) | ((pix >> 16) & 0xff) | ((pix & 0xff) << 16);
    268 #endif
    269                 d[0] = pix;
    270             }
    271         }
    272 
    273         SDL_Surface* icon = sdl_surface_from_argb32( icon_pixels, icon_w, icon_h );
    274         if (icon != NULL) {
    275             SDL_WM_SetIcon(icon, NULL);
    276             SDL_FreeSurface(icon);
    277             free( icon_pixels );
    278         }
    279 #endif  /* !_WIN32 */
    280     }
    281 }
    282 
    283 /***********************************************************************/
    284 /***********************************************************************/
    285 /*****                                                             *****/
    286 /*****            S K I N   S U P P O R T                          *****/
    287 /*****                                                             *****/
    288 /***********************************************************************/
    289 /***********************************************************************/
    290 
    291 const char*  skin_network_speed = NULL;
    292 const char*  skin_network_delay = NULL;
    293 
    294 
    295 static void sdl_at_exit(void)
    296 {
    297     user_config_done();
    298     qemulator_done(qemulator_get());
    299     SDL_Quit();
    300 }
    301 
    302 
    303 void sdl_display_init(DisplayState *ds, int full_screen, int  no_frame)
    304 {
    305     QEmulator*    emulator = qemulator_get();
    306     SkinDisplay*  disp     = skin_layout_get_display(emulator->layout);
    307     int           width, height;
    308     char          buf[128];
    309 
    310     if (disp->rotation & 1) {
    311         width  = disp->rect.size.h;
    312         height = disp->rect.size.w;
    313     } else {
    314         width  = disp->rect.size.w;
    315         height = disp->rect.size.h;
    316     }
    317 
    318     snprintf(buf, sizeof buf, "width=%d,height=%d", width, height);
    319 #if !defined(CONFIG_STANDALONE_UI) && !defined(CONFIG_STANDALONE_CORE)
    320     android_display_init(ds, qframebuffer_fifo_get());
    321 #endif
    322 }
    323 
    324 /* list of skin aliases */
    325 static const struct {
    326     const char*  name;
    327     const char*  alias;
    328 } skin_aliases[] = {
    329     { "QVGA-L", "320x240" },
    330     { "QVGA-P", "240x320" },
    331     { "HVGA-L", "480x320" },
    332     { "HVGA-P", "320x480" },
    333     { "QVGA", "320x240" },
    334     { "HVGA", "320x480" },
    335     { NULL, NULL }
    336 };
    337 
    338 void
    339 parse_skin_files(const char*      skinDirPath,
    340                  const char*      skinName,
    341                  AndroidOptions*  opts,
    342                  AndroidHwConfig* hwConfig,
    343                  AConfig*        *skinConfig,
    344                  char*           *skinPath)
    345 {
    346     char      tmp[1024];
    347     AConfig*  root;
    348     const char* path = NULL;
    349     AConfig*  n;
    350 
    351     root = aconfig_node("", "");
    352 
    353     if (skinName == NULL)
    354         goto DEFAULT_SKIN;
    355 
    356     /* Support skin aliases like QVGA-H QVGA-P, etc...
    357        But first we check if it's a directory that exist before applying
    358        the alias */
    359     int  checkAlias = 1;
    360 
    361     if (skinDirPath != NULL) {
    362         bufprint(tmp, tmp+sizeof(tmp), "%s/%s", skinDirPath, skinName);
    363         if (path_exists(tmp)) {
    364             checkAlias = 0;
    365         } else {
    366             D("there is no '%s' skin in '%s'", skinName, skinDirPath);
    367         }
    368     }
    369 
    370     if (checkAlias) {
    371         int  nn;
    372 
    373         for (nn = 0; ; nn++ ) {
    374             const char*  skin_name  = skin_aliases[nn].name;
    375             const char*  skin_alias = skin_aliases[nn].alias;
    376 
    377             if (!skin_name)
    378                 break;
    379 
    380             if (!strcasecmp( skin_name, skinName )) {
    381                 D("skin name '%s' aliased to '%s'", skinName, skin_alias);
    382                 skinName = skin_alias;
    383                 break;
    384             }
    385         }
    386     }
    387 
    388     /* Magically support skins like "320x240" or "320x240x16" */
    389     if(isdigit(skinName[0])) {
    390         char *x = strchr(skinName, 'x');
    391         if(x && isdigit(x[1])) {
    392             int width = atoi(skinName);
    393             int height = atoi(x+1);
    394             int bpp   = 16;
    395             char* y = strchr(x+1, 'x');
    396             if (y && isdigit(y[1])) {
    397                 bpp = atoi(y+1);
    398             }
    399             snprintf(tmp, sizeof tmp,
    400                         "display {\n  width %d\n  height %d\n bpp %d}\n",
    401                         width, height,bpp);
    402             aconfig_load(root, strdup(tmp));
    403             path = ":";
    404             D("found magic skin width=%d height=%d bpp=%d\n", width, height, bpp);
    405             goto FOUND_SKIN;
    406         }
    407     }
    408 
    409     if (skinDirPath == NULL) {
    410         derror("unknown skin name '%s'", skinName);
    411         exit(1);
    412     }
    413 
    414     snprintf(tmp, sizeof tmp, "%s/%s/layout", skinDirPath, skinName);
    415     D("trying to load skin file '%s'", tmp);
    416 
    417     if(aconfig_load_file(root, tmp) < 0) {
    418         dwarning("could not load skin file '%s', using built-in one\n",
    419                  tmp);
    420         goto DEFAULT_SKIN;
    421     }
    422 
    423     snprintf(tmp, sizeof tmp, "%s/%s/", skinDirPath, skinName);
    424     path = tmp;
    425     goto FOUND_SKIN;
    426 
    427 FOUND_SKIN:
    428     /* the default network speed and latency can now be specified by the device skin */
    429     n = aconfig_find(root, "network");
    430     if (n != NULL) {
    431         skin_network_speed = aconfig_str(n, "speed", 0);
    432         skin_network_delay = aconfig_str(n, "delay", 0);
    433     }
    434 
    435     /* extract framebuffer information from the skin.
    436      *
    437      * for version 1 of the skin format, they are in the top-level
    438      * 'display' element.
    439      *
    440      * for version 2 of the skin format, they are under parts.device.display
    441      */
    442     n = aconfig_find(root, "display");
    443     if (n == NULL) {
    444         n = aconfig_find(root, "parts");
    445         if (n != NULL) {
    446             n = aconfig_find(n, "device");
    447             if (n != NULL) {
    448                 n = aconfig_find(n, "display");
    449             }
    450         }
    451     }
    452 
    453     if (n != NULL) {
    454         int  width  = aconfig_int(n, "width", hwConfig->hw_lcd_width);
    455         int  height = aconfig_int(n, "height", hwConfig->hw_lcd_height);
    456         int  depth  = aconfig_int(n, "bpp", hwConfig->hw_lcd_depth);
    457 
    458         if (width > 0 && height > 0) {
    459             /* The emulated framebuffer wants sizes that are multiples of 4 */
    460             if (((width|height) & 3) != 0) {
    461                 width  = (width+3) & ~3;
    462                 height = (height+3) & ~3;
    463                 D("adjusting LCD dimensions to (%dx%dx)", width, height);
    464             }
    465 
    466             /* only depth values of 16 and 32 are correct. 16 is the default. */
    467             if (depth != 32 && depth != 16) {
    468                 depth = 16;
    469                 D("adjusting LCD bit depth to %d", depth);
    470             }
    471 
    472             hwConfig->hw_lcd_width  = width;
    473             hwConfig->hw_lcd_height = height;
    474             hwConfig->hw_lcd_depth  = depth;
    475         }
    476         else {
    477             D("ignoring invalid skin LCD dimensions (%dx%dx%d)",
    478               width, height, depth);
    479         }
    480     }
    481 
    482     *skinConfig = root;
    483     *skinPath   = strdup(path);
    484     return;
    485 
    486 DEFAULT_SKIN:
    487     {
    488         const unsigned char*  layout_base;
    489         size_t                layout_size;
    490         char*                 base;
    491 
    492         skinName = "<builtin>";
    493 
    494         layout_base = android_resource_find( "layout", &layout_size );
    495         if (layout_base == NULL) {
    496             fprintf(stderr, "Couldn't load builtin skin\n");
    497             exit(1);
    498         }
    499         base = malloc( layout_size+1 );
    500         memcpy( base, layout_base, layout_size );
    501         base[layout_size] = 0;
    502 
    503         D("parsing built-in skin layout file (%d bytes)", (int)layout_size);
    504         aconfig_load(root, base);
    505         path = ":";
    506     }
    507     goto FOUND_SKIN;
    508 }
    509 
    510 
    511 void
    512 init_sdl_ui(AConfig*         skinConfig,
    513             const char*      skinPath,
    514             AndroidOptions*  opts)
    515 {
    516     int  win_x, win_y, flags;
    517 
    518     signal(SIGINT, SIG_DFL);
    519 #ifndef _WIN32
    520     signal(SIGQUIT, SIG_DFL);
    521 #endif
    522 
    523     /* we're not a game, so allow the screensaver to run */
    524     setenv("SDL_VIDEO_ALLOW_SCREENSAVER","1",1);
    525 
    526     flags = SDL_INIT_NOPARACHUTE;
    527     if (!opts->no_window)
    528         flags |= SDL_INIT_VIDEO;
    529 
    530     if(SDL_Init(flags)){
    531         fprintf(stderr, "SDL init failure, reason is: %s\n", SDL_GetError() );
    532         exit(1);
    533     }
    534 
    535     if (!opts->no_window) {
    536         SDL_EnableUNICODE(!opts->raw_keys);
    537         SDL_EnableKeyRepeat(0,0);
    538 
    539         sdl_set_window_icon();
    540     }
    541     else
    542     {
    543 #ifndef _WIN32
    544        /* prevent SIGTTIN and SIGTTOUT from stopping us. this is necessary to be
    545         * able to run the emulator in the background (e.g. "emulator &").
    546         * despite the fact that the emulator should not grab input or try to
    547         * write to the output in normal cases, we're stopped on some systems
    548         * (e.g. OS X)
    549         */
    550         signal(SIGTTIN, SIG_IGN);
    551         signal(SIGTTOU, SIG_IGN);
    552 #endif
    553     }
    554     atexit(sdl_at_exit);
    555 
    556     user_config_get_window_pos(&win_x, &win_y);
    557 
    558     if ( qemulator_init(qemulator_get(), skinConfig, skinPath, win_x, win_y, opts) < 0 ) {
    559         fprintf(stderr, "### Error: could not load emulator skin from '%s'\n", skinPath);
    560         exit(1);
    561     }
    562 
    563     /* add an onion overlay image if needed */
    564     if (opts->onion) {
    565         SkinImage*  onion = skin_image_find_simple( opts->onion );
    566         int         alpha, rotate;
    567 
    568         if ( opts->onion_alpha && 1 == sscanf( opts->onion_alpha, "%d", &alpha ) ) {
    569             alpha = (256*alpha)/100;
    570         } else
    571             alpha = 128;
    572 
    573         if ( opts->onion_rotation && 1 == sscanf( opts->onion_rotation, "%d", &rotate ) ) {
    574             rotate &= 3;
    575         } else
    576             rotate = SKIN_ROTATION_0;
    577 
    578         qemulator_get()->onion          = onion;
    579         qemulator_get()->onion_alpha    = alpha;
    580         qemulator_get()->onion_rotation = rotate;
    581     }
    582 }
    583 
    584 /* this function is used to perform auto-detection of the
    585  * system directory in the case of a SDK installation.
    586  *
    587  * we want to deal with several historical usages, hence
    588  * the slightly complicated logic.
    589  *
    590  * NOTE: the function returns the path to the directory
    591  *       containing 'fileName'. this is *not* the full
    592  *       path to 'fileName'.
    593  */
    594 static char*
    595 _getSdkImagePath( const char*  fileName )
    596 {
    597     char   temp[MAX_PATH];
    598     char*  p   = temp;
    599     char*  end = p + sizeof(temp);
    600     char*  q;
    601     char*  app;
    602 
    603     static const char* const  searchPaths[] = {
    604         "",                                  /* program's directory */
    605         "/lib/images",                       /* this is for SDK 1.0 */
    606         "/../platforms/android-1.1/images",  /* this is for SDK 1.1 */
    607         NULL
    608     };
    609 
    610     app = bufprint_app_dir(temp, end);
    611     if (app >= end)
    612         return NULL;
    613 
    614     do {
    615         int  nn;
    616 
    617         /* first search a few well-known paths */
    618         for (nn = 0; searchPaths[nn] != NULL; nn++) {
    619             p = bufprint(app, end, "%s", searchPaths[nn]);
    620             q = bufprint(p, end, "/%s", fileName);
    621             if (q < end && path_exists(temp)) {
    622                 *p = 0;
    623                 goto FOUND_IT;
    624             }
    625         }
    626 
    627         /* hmmm. let's assume that we are in a post-1.1 SDK
    628          * scan ../platforms if it exists
    629          */
    630         p = bufprint(app, end, "/../platforms");
    631         if (p < end) {
    632             DirScanner*  scanner = dirScanner_new(temp);
    633             if (scanner != NULL) {
    634                 int          found = 0;
    635                 const char*  subdir;
    636 
    637                 for (;;) {
    638                     subdir = dirScanner_next(scanner);
    639                     if (!subdir) break;
    640 
    641                     q = bufprint(p, end, "/%s/images/%s", subdir, fileName);
    642                     if (q >= end || !path_exists(temp))
    643                         continue;
    644 
    645                     found = 1;
    646                     p = bufprint(p, end, "/%s/images", subdir);
    647                     break;
    648                 }
    649                 dirScanner_free(scanner);
    650                 if (found)
    651                     break;
    652             }
    653         }
    654 
    655         /* I'm out of ideas */
    656         return NULL;
    657 
    658     } while (0);
    659 
    660 FOUND_IT:
    661     //D("image auto-detection: %s/%s", temp, fileName);
    662     return android_strdup(temp);
    663 }
    664 
    665 static char*
    666 _getSdkImage( const char*  path, const char*  file )
    667 {
    668     char  temp[MAX_PATH];
    669     char  *p = temp, *end = p + sizeof(temp);
    670 
    671     p = bufprint(temp, end, "%s/%s", path, file);
    672     if (p >= end || !path_exists(temp))
    673         return NULL;
    674 
    675     return android_strdup(temp);
    676 }
    677 
    678 static char*
    679 _getSdkSystemImage( const char*  path, const char*  optionName, const char*  file )
    680 {
    681     char*  image = _getSdkImage(path, file);
    682 
    683     if (image == NULL) {
    684         derror("Your system directory is missing the '%s' image file.\n"
    685                "Please specify one with the '%s <filepath>' option",
    686                file, optionName);
    687         exit(2);
    688     }
    689     return image;
    690 }
    691 
    692 void sanitizeOptions( AndroidOptions* opts )
    693 {
    694     /* legacy support: we used to use -system <dir> and -image <file>
    695      * instead of -sysdir <dir> and -system <file>, so handle this by checking
    696      * whether the options point to directories or files.
    697      */
    698     if (opts->image != NULL) {
    699         if (opts->system != NULL) {
    700             if (opts->sysdir != NULL) {
    701                 derror( "You can't use -sysdir, -system and -image at the same time.\n"
    702                         "You should probably use '-sysdir <path> -system <file>'.\n" );
    703                 exit(2);
    704             }
    705         }
    706         dwarning( "Please note that -image is obsolete and that -system is now used to point\n"
    707                   "to the system image. Next time, try using '-sysdir <path> -system <file>' instead.\n" );
    708         opts->sysdir = opts->system;
    709         opts->system = opts->image;
    710         opts->image  = NULL;
    711     }
    712     else if (opts->system != NULL && path_is_dir(opts->system)) {
    713         if (opts->sysdir != NULL) {
    714             derror( "Option -system should now be followed by a file path, not a directory one.\n"
    715                     "Please use '-sysdir <path>' to point to the system directory.\n" );
    716             exit(1);
    717         }
    718         dwarning( "Please note that the -system option should now be used to point to the initial\n"
    719                   "system image (like the obsolete -image option). To point to the system directory\n"
    720                   "please now use '-sysdir <path>' instead.\n" );
    721 
    722         opts->sysdir = opts->system;
    723         opts->system = NULL;
    724     }
    725 
    726     if (opts->nojni) {
    727         opts->no_jni = opts->nojni;
    728         opts->nojni  = 0;
    729     }
    730 
    731     if (opts->nocache) {
    732         opts->no_cache = opts->nocache;
    733         opts->nocache  = 0;
    734     }
    735 
    736     if (opts->noaudio) {
    737         opts->no_audio = opts->noaudio;
    738         opts->noaudio  = 0;
    739     }
    740 
    741     if (opts->noskin) {
    742         opts->no_skin = opts->noskin;
    743         opts->noskin  = 0;
    744     }
    745 
    746     /* If -no-cache is used, ignore any -cache argument */
    747     if (opts->no_cache) {
    748         opts->cache = 0;
    749     }
    750 
    751     /* the purpose of -no-audio is to disable sound output from the emulator,
    752      * not to disable Audio emulation. So simply force the 'none' backends */
    753     if (opts->no_audio)
    754         opts->audio = "none";
    755 
    756     /* we don't accept -skindir without -skin now
    757      * to simplify the autoconfig stuff with virtual devices
    758      */
    759     if (opts->no_skin) {
    760         opts->skin    = "320x480";
    761         opts->skindir = NULL;
    762     }
    763 
    764     if (opts->skindir) {
    765         if (!opts->skin) {
    766             derror( "the -skindir <path> option requires a -skin <name> option");
    767             exit(1);
    768         }
    769     }
    770 
    771     if (opts->bootchart) {
    772         char*  end;
    773         int    timeout = strtol(opts->bootchart, &end, 10);
    774         if (timeout == 0)
    775             opts->bootchart = NULL;
    776         else if (timeout < 0 || timeout > 15*60) {
    777             derror( "timeout specified for -bootchart option is invalid.\n"
    778                     "please use integers between 1 and 900\n");
    779             exit(1);
    780         }
    781     }
    782 }
    783 
    784 AvdInfo* createAVD(AndroidOptions* opts, int* inAndroidBuild)
    785 {
    786     AvdInfo* ret = NULL;
    787     char   tmp[MAX_PATH];
    788     char*  tmpend = tmp + sizeof(tmp);
    789     char*  android_build_root = NULL;
    790     char*  android_build_out  = NULL;
    791 
    792     /* If no AVD name was given, try to find the top of the
    793      * Android build tree
    794      */
    795     if (opts->avd == NULL) {
    796         do {
    797             char*  out = getenv("ANDROID_PRODUCT_OUT");
    798 
    799             if (out == NULL || out[0] == 0)
    800                 break;
    801 
    802             if (!path_exists(out)) {
    803                 derror("Can't access ANDROID_PRODUCT_OUT as '%s'\n"
    804                     "You need to build the Android system before launching the emulator",
    805                     out);
    806                 exit(2);
    807             }
    808 
    809             android_build_root = path_parent( out, 4 );
    810             if (android_build_root == NULL || !path_exists(android_build_root)) {
    811                 derror("Can't find the Android build root from '%s'\n"
    812                     "Please check the definition of the ANDROID_PRODUCT_OUT variable.\n"
    813                     "It should point to your product-specific build output directory.\n",
    814                     out );
    815                 exit(2);
    816             }
    817             android_build_out = out;
    818             D( "found Android build root: %s", android_build_root );
    819             D( "found Android build out:  %s", android_build_out );
    820         } while (0);
    821     }
    822     /* if no virtual device name is given, and we're not in the
    823      * Android build system, we'll need to perform some auto-detection
    824      * magic :-)
    825      */
    826     if (opts->avd == NULL && !android_build_out)
    827     {
    828         char   dataDirIsSystem = 0;
    829 
    830         if (!opts->sysdir) {
    831             opts->sysdir = _getSdkImagePath("system.img");
    832             if (!opts->sysdir) {
    833                 derror(
    834                 "You did not specify a virtual device name, and the system\n"
    835                 "directory could not be found.\n\n"
    836                 "If you are an Android SDK user, please use '@<name>' or '-avd <name>'\n"
    837                 "to start a given virtual device (see -help-avd for details).\n\n"
    838 
    839                 "Otherwise, follow the instructions in -help-disk-images to start the emulator\n"
    840                 );
    841                 exit(2);
    842             }
    843             D("autoconfig: -sysdir %s", opts->sysdir);
    844         }
    845 
    846         if (!opts->system) {
    847             opts->system = _getSdkSystemImage(opts->sysdir, "-image", "system.img");
    848             D("autoconfig: -system %s", opts->system);
    849         }
    850 
    851         if (!opts->kernel) {
    852             opts->kernel = _getSdkSystemImage(opts->sysdir, "-kernel", "kernel-qemu");
    853             D("autoconfig: -kernel %s", opts->kernel);
    854         }
    855 
    856         if (!opts->ramdisk) {
    857             opts->ramdisk = _getSdkSystemImage(opts->sysdir, "-ramdisk", "ramdisk.img");
    858             D("autoconfig: -ramdisk %s", opts->ramdisk);
    859         }
    860 
    861         /* if no data directory is specified, use the system directory */
    862         if (!opts->datadir) {
    863             opts->datadir   = android_strdup(opts->sysdir);
    864             dataDirIsSystem = 1;
    865             D("autoconfig: -datadir %s", opts->sysdir);
    866         }
    867 
    868         if (!opts->data) {
    869             /* check for userdata-qemu.img in the data directory */
    870             bufprint(tmp, tmpend, "%s/userdata-qemu.img", opts->datadir);
    871             if (!path_exists(tmp)) {
    872                 derror(
    873                 "You did not provide the name of an Android Virtual Device\n"
    874                 "with the '-avd <name>' option. Read -help-avd for more information.\n\n"
    875 
    876                 "If you *really* want to *NOT* run an AVD, consider using '-data <file>'\n"
    877                 "to specify a data partition image file (I hope you know what you're doing).\n"
    878                 );
    879                 exit(2);
    880             }
    881 
    882             opts->data = android_strdup(tmp);
    883             D("autoconfig: -data %s", opts->data);
    884         }
    885 
    886         if (!opts->snapstorage && opts->datadir) {
    887             bufprint(tmp, tmpend, "%s/snapshots.img", opts->datadir);
    888             if (path_exists(tmp)) {
    889                 opts->snapstorage = android_strdup(tmp);
    890                 D("autoconfig: -snapstorage %s", opts->snapstorage);
    891             }
    892         }
    893     }
    894 
    895     /* setup the virtual device differently depending on whether
    896      * we are in the Android build system or not
    897      */
    898     if (opts->avd != NULL)
    899     {
    900         ret = avdInfo_new( opts->avd, android_avdParams );
    901         if (ret == NULL) {
    902             /* an error message has already been printed */
    903             dprint("could not find virtual device named '%s'", opts->avd);
    904             exit(1);
    905         }
    906     }
    907     else
    908     {
    909         if (!android_build_out) {
    910             android_build_out = android_build_root = opts->sysdir;
    911         }
    912         ret = avdInfo_newForAndroidBuild(
    913                             android_build_root,
    914                             android_build_out,
    915                             android_avdParams );
    916 
    917         if(ret == NULL) {
    918             D("could not start virtual device\n");
    919             exit(1);
    920         }
    921     }
    922 
    923     if (android_build_out) {
    924         *inAndroidBuild = 1;
    925     } else {
    926         *inAndroidBuild = 0;
    927     }
    928 
    929     return ret;
    930 }
    931 
    932 
    933 
    934 
    935 #ifdef CONFIG_STANDALONE_UI
    936 
    937 #include "android/protocol/core-connection.h"
    938 #include "android/protocol/fb-updates-impl.h"
    939 #include "android/protocol/user-events-proxy.h"
    940 #include "android/protocol/core-commands-proxy.h"
    941 #include "android/protocol/ui-commands-impl.h"
    942 #include "android/protocol/attach-ui-impl.h"
    943 
    944 /* Emulator's core port. */
    945 int android_base_port = 0;
    946 
    947 // Base console port
    948 #define CORE_BASE_PORT          5554
    949 
    950 // Maximum number of core porocesses running simultaneously on a machine.
    951 #define MAX_CORE_PROCS          16
    952 
    953 // Socket timeout in millisec (set to 5 seconds)
    954 #define CORE_PORT_TIMEOUT_MS    5000
    955 
    956 #include "android/async-console.h"
    957 
    958 typedef struct {
    959     LoopIo                 io[1];
    960     int                    port;
    961     int                    ok;
    962     AsyncConsoleConnector  connector[1];
    963 } CoreConsole;
    964 
    965 static void
    966 coreconsole_io_func(void* opaque, int fd, unsigned events)
    967 {
    968     CoreConsole* cc = opaque;
    969     AsyncStatus  status;
    970     status = asyncConsoleConnector_run(cc->connector);
    971     if (status == ASYNC_COMPLETE) {
    972         cc->ok = 1;
    973     }
    974 }
    975 
    976 static void
    977 coreconsole_init(CoreConsole* cc, const SockAddress* address, Looper* looper)
    978 {
    979     int fd = socket_create_inet(SOCKET_STREAM);
    980     AsyncStatus status;
    981     cc->port = sock_address_get_port(address);
    982     cc->ok   = 0;
    983     loopIo_init(cc->io, looper, fd, coreconsole_io_func, cc);
    984     if (fd >= 0) {
    985         status = asyncConsoleConnector_connect(cc->connector, address, cc->io);
    986         if (status == ASYNC_ERROR) {
    987             cc->ok = 0;
    988         }
    989     }
    990 }
    991 
    992 static void
    993 coreconsole_done(CoreConsole* cc)
    994 {
    995     socket_close(cc->io->fd);
    996     loopIo_done(cc->io);
    997 }
    998 
    999 /* List emulator core processes running on the given machine.
   1000  * This routine is called from main() if -list-cores parameter is set in the
   1001  * command line.
   1002  * Param:
   1003  *  host Value passed with -list-core parameter. Must be either "localhost", or
   1004  *  an IP address of a machine where core processes must be enumerated.
   1005  */
   1006 static void
   1007 list_running_cores(const char* host)
   1008 {
   1009     Looper*         looper;
   1010     CoreConsole     cores[MAX_CORE_PROCS];
   1011     SockAddress     address;
   1012     int             nn, found;
   1013 
   1014     if (sock_address_init_resolve(&address, host, CORE_BASE_PORT, 0) < 0) {
   1015         derror("Unable to resolve hostname %s: %s", host, errno_str);
   1016         return;
   1017     }
   1018 
   1019     looper = looper_newGeneric();
   1020 
   1021     for (nn = 0; nn < MAX_CORE_PROCS; nn++) {
   1022         int port = CORE_BASE_PORT + nn*2;
   1023         sock_address_set_port(&address, port);
   1024         coreconsole_init(&cores[nn], &address, looper);
   1025     }
   1026 
   1027     looper_runWithTimeout(looper, CORE_PORT_TIMEOUT_MS*2);
   1028 
   1029     found = 0;
   1030     for (nn = 0; nn < MAX_CORE_PROCS; nn++) {
   1031         int port = CORE_BASE_PORT + nn*2;
   1032         if (cores[nn].ok) {
   1033             if (found == 0) {
   1034                 fprintf(stdout, "Running emulator core processes:\n");
   1035             }
   1036             fprintf(stdout, "Emulator console port %d\n", port);
   1037             found++;
   1038         }
   1039         coreconsole_done(&cores[nn]);
   1040     }
   1041     looper_free(looper);
   1042 
   1043     if (found == 0) {
   1044        fprintf(stdout, "There were no running emulator core processes found on %s.\n",
   1045                host);
   1046     }
   1047 }
   1048 
   1049 /* Attaches starting UI to a running core process.
   1050  * This routine is called from main() when -attach-core parameter is set,
   1051  * indicating that this UI instance should attach to a running core, rather than
   1052  * start a new core process.
   1053  * Param:
   1054  *  opts Android options containing non-NULL attach_core.
   1055  * Return:
   1056  *  0 on success, or -1 on failure.
   1057  */
   1058 static int
   1059 attach_to_core(AndroidOptions* opts) {
   1060     int iter;
   1061     SockAddress console_socket;
   1062     SockAddress** sockaddr_list;
   1063     QEmulator* emulator;
   1064 
   1065     // Parse attach_core param extracting the host name, and the port name.
   1066     char* console_address = strdup(opts->attach_core);
   1067     char* host_name = console_address;
   1068     char* port_num = strchr(console_address, ':');
   1069     if (port_num == NULL) {
   1070         // The host name is ommited, indicating the localhost
   1071         host_name = "localhost";
   1072         port_num = console_address;
   1073     } else if (port_num == console_address) {
   1074         // Invalid.
   1075         derror("Invalid value %s for -attach-core parameter\n",
   1076                opts->attach_core);
   1077         return -1;
   1078     } else {
   1079         *port_num = '\0';
   1080         port_num++;
   1081         if (*port_num == '\0') {
   1082             // Invalid.
   1083             derror("Invalid value %s for -attach-core parameter\n",
   1084                    opts->attach_core);
   1085             return -1;
   1086         }
   1087     }
   1088 
   1089     /* Create socket address list for the given address, and pull appropriate
   1090      * address to use for connection. Note that we're fine copying that address
   1091      * out of the list, since INET and IN6 will entirely fit into SockAddress
   1092      * structure. */
   1093     sockaddr_list =
   1094         sock_address_list_create(host_name, port_num, SOCKET_LIST_FORCE_INET);
   1095     free(console_address);
   1096     if (sockaddr_list == NULL) {
   1097         derror("Unable to resolve address %s: %s\n",
   1098                opts->attach_core, errno_str);
   1099         return -1;
   1100     }
   1101     for (iter = 0; sockaddr_list[iter] != NULL; iter++) {
   1102         if (sock_address_get_family(sockaddr_list[iter]) == SOCKET_INET ||
   1103             sock_address_get_family(sockaddr_list[iter]) == SOCKET_IN6) {
   1104             memcpy(&console_socket, sockaddr_list[iter], sizeof(SockAddress));
   1105             break;
   1106         }
   1107     }
   1108     if (sockaddr_list[iter] == NULL) {
   1109         derror("Unable to resolve address %s. Note that 'port' parameter passed to -attach-core\n"
   1110                "must be resolvable into an IP address.\n", opts->attach_core);
   1111         sock_address_list_free(sockaddr_list);
   1112         return -1;
   1113     }
   1114     sock_address_list_free(sockaddr_list);
   1115 
   1116     if (attachUiImpl_create(&console_socket)) {
   1117         return -1;
   1118     }
   1119 
   1120     // Save core's port, and set the title.
   1121     android_base_port = sock_address_get_port(&console_socket);
   1122     emulator = qemulator_get();
   1123     qemulator_set_title(emulator);
   1124 
   1125     return 0;
   1126 }
   1127 
   1128 
   1129 void handle_ui_options( AndroidOptions* opts )
   1130 {
   1131     // Lets see if user just wants to list core process.
   1132     if (opts->list_cores) {
   1133         fprintf(stdout, "Enumerating running core processes.\n");
   1134         list_running_cores(opts->list_cores);
   1135         exit(0);
   1136     }
   1137 }
   1138 
   1139 int attach_ui_to_core( AndroidOptions* opts )
   1140 {
   1141     // Lets see if we're attaching to a running core process here.
   1142     if (opts->attach_core) {
   1143         if (attach_to_core(opts)) {
   1144             return -1;
   1145         }
   1146         // Connect to the core's UI control services.
   1147         if (coreCmdProxy_create(attachUiImpl_get_console_socket())) {
   1148             return -1;
   1149         }
   1150         // Connect to the core's user events service.
   1151         if (userEventsProxy_create(attachUiImpl_get_console_socket())) {
   1152             return -1;
   1153         }
   1154     }
   1155     return 0;
   1156 }
   1157 
   1158 #else  /* !CONFIG_STANDALONE_UI */
   1159 
   1160 void handle_ui_options( AndroidOptions* opts )
   1161 {
   1162     return;
   1163 }
   1164 
   1165 int attach_ui_to_core( AndroidOptions* opts )
   1166 {
   1167     return 0;
   1168 }
   1169 
   1170 #endif /* CONFIG_STANDALONE_UI */
   1171