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