1f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner/* Copyright (C) 2011 The Android Open Source Project
2f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner**
3f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner** This software is licensed under the terms of the GNU General Public
4f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner** License version 2, as published by the Free Software Foundation, and
5f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner** may be copied, distributed, and modified under those terms.
6f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner**
7f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner** This program is distributed in the hope that it will be useful,
8f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner** but WITHOUT ANY WARRANTY; without even the implied warranty of
9f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner** GNU General Public License for more details.
11f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner*/
1209aa9774a68528f2269813833e2313e20d60d0d3Siva Velusamy#include "android/avd/util.h"
13d174434fbf6fbfce54f7eabaa54b8296f55527b8David 'Digit' Turner#include "android/utils/bufprint.h"
14f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner#include "android/utils/debug.h"
1552e9942c2e0ffac6f7ccc2d2c916c855ad62c33dDavid 'Digit' Turner#include "android/utils/eintr_wrapper.h"
16f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner#include "android/utils/path.h"
1783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine#include "android/utils/dirscanner.h"
18f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner#include "android/main-common.h"
19f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner#include "android/globals.h"
20f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner#include "android/resource.h"
21f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner#include "android/user-config.h"
22f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner
23d174434fbf6fbfce54f7eabaa54b8296f55527b8David 'Digit' Turner#include <errno.h>
24d174434fbf6fbfce54f7eabaa54b8296f55527b8David 'Digit' Turner#include <fcntl.h>
25d174434fbf6fbfce54f7eabaa54b8296f55527b8David 'Digit' Turner#include <limits.h>
26d174434fbf6fbfce54f7eabaa54b8296f55527b8David 'Digit' Turner#ifdef _WIN32
27d174434fbf6fbfce54f7eabaa54b8296f55527b8David 'Digit' Turner#include <process.h>
28d174434fbf6fbfce54f7eabaa54b8296f55527b8David 'Digit' Turner#endif
29d174434fbf6fbfce54f7eabaa54b8296f55527b8David 'Digit' Turner#include <signal.h>
30d174434fbf6fbfce54f7eabaa54b8296f55527b8David 'Digit' Turner#include <stdlib.h>
31d174434fbf6fbfce54f7eabaa54b8296f55527b8David 'Digit' Turner#include <string.h>
32d174434fbf6fbfce54f7eabaa54b8296f55527b8David 'Digit' Turner#include <sys/time.h>
33d174434fbf6fbfce54f7eabaa54b8296f55527b8David 'Digit' Turner#include <unistd.h>
34f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner
35f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner
36f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner/***********************************************************************/
37f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner/***********************************************************************/
38f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner/*****                                                             *****/
39f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner/*****            U T I L I T Y   R O U T I N E S                  *****/
40f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner/*****                                                             *****/
41f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner/***********************************************************************/
42f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner/***********************************************************************/
43f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner
44f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner#define  D(...)  do {  if (VERBOSE_CHECK(init)) dprint(__VA_ARGS__); } while (0)
45f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner
46c5f12b935ced6c029244b1a3230edc9b7646da97David 'Digit' Turnervoid reassign_string(char** string, const char* new_value) {
47c5f12b935ced6c029244b1a3230edc9b7646da97David 'Digit' Turner    free(*string);
48c5f12b935ced6c029244b1a3230edc9b7646da97David 'Digit' Turner    *string = ASTRDUP(new_value);
49c5f12b935ced6c029244b1a3230edc9b7646da97David 'Digit' Turner}
50c5f12b935ced6c029244b1a3230edc9b7646da97David 'Digit' Turner
51f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turnerunsigned convertBytesToMB( uint64_t  size )
52f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner{
53f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner    if (size == 0)
54f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner        return 0;
55f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner
56f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner    size = (size + ONE_MB-1) >> 20;
57f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner    if (size > UINT_MAX)
58f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner        size = UINT_MAX;
59f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner
60f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner    return (unsigned) size;
61f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner}
62f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner
63f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turneruint64_t convertMBToBytes( unsigned  megaBytes )
64f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner{
65f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner    return ((uint64_t)megaBytes << 20);
66f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner}
67f845627c83ce6ce3e306f9b6842d1e30ef89ae97David 'Digit' Turner
6883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine/* this function is used to perform auto-detection of the
6983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine * system directory in the case of a SDK installation.
7083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine *
7183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine * we want to deal with several historical usages, hence
7283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine * the slightly complicated logic.
7383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine *
7483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine * NOTE: the function returns the path to the directory
7583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine *       containing 'fileName'. this is *not* the full
7683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine *       path to 'fileName'.
7783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine */
7883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkinestatic char*
7983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine_getSdkImagePath( const char*  fileName )
8083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine{
8183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    char   temp[MAX_PATH];
8283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    char*  p   = temp;
8383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    char*  end = p + sizeof(temp);
8483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    char*  q;
8583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    char*  app;
8683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
8783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    static const char* const  searchPaths[] = {
8883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        "",                                  /* program's directory */
8983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        "/lib/images",                       /* this is for SDK 1.0 */
9083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        "/../platforms/android-1.1/images",  /* this is for SDK 1.1 */
9183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        NULL
9283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    };
9383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
9483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    app = bufprint_app_dir(temp, end);
9583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    if (app >= end)
9683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        return NULL;
9783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
9883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    do {
9983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        int  nn;
10083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
10183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        /* first search a few well-known paths */
10283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        for (nn = 0; searchPaths[nn] != NULL; nn++) {
10383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            p = bufprint(app, end, "%s", searchPaths[nn]);
10483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            q = bufprint(p, end, "/%s", fileName);
10583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            if (q < end && path_exists(temp)) {
10683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                *p = 0;
10783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                goto FOUND_IT;
10883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            }
10983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        }
11083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
11183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        /* hmmm. let's assume that we are in a post-1.1 SDK
11283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine         * scan ../platforms if it exists
11383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine         */
11483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        p = bufprint(app, end, "/../platforms");
11583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        if (p < end) {
11683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            DirScanner*  scanner = dirScanner_new(temp);
11783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            if (scanner != NULL) {
11883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                int          found = 0;
11983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                const char*  subdir;
12083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
12183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                for (;;) {
12283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                    subdir = dirScanner_next(scanner);
12383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                    if (!subdir) break;
12483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
12583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                    q = bufprint(p, end, "/%s/images/%s", subdir, fileName);
12683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                    if (q >= end || !path_exists(temp))
12783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                        continue;
12883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
12983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                    found = 1;
13083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                    p = bufprint(p, end, "/%s/images", subdir);
13183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                    break;
13283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                }
13383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                dirScanner_free(scanner);
13483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                if (found)
13583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                    break;
13683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            }
13783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        }
13883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
13983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        /* I'm out of ideas */
14083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        return NULL;
14183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
14283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    } while (0);
14383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
14483ffd66e78d290aa054ace5e484ae3766f638390Vladimir ChtchetkineFOUND_IT:
14583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    //D("image auto-detection: %s/%s", temp, fileName);
14683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    return android_strdup(temp);
14783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine}
14883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
14983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkinestatic char*
15083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine_getSdkImage( const char*  path, const char*  file )
15183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine{
15283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    char  temp[MAX_PATH];
15383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    char  *p = temp, *end = p + sizeof(temp);
15483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
15583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    p = bufprint(temp, end, "%s/%s", path, file);
15683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    if (p >= end || !path_exists(temp))
15783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        return NULL;
15883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
15983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    return android_strdup(temp);
16083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine}
16183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
16283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkinestatic char*
16383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine_getSdkSystemImage( const char*  path, const char*  optionName, const char*  file )
16483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine{
16583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    char*  image = _getSdkImage(path, file);
16683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
16783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    if (image == NULL) {
16883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        derror("Your system directory is missing the '%s' image file.\n"
16983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine               "Please specify one with the '%s <filepath>' option",
17083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine               file, optionName);
17183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        exit(2);
17283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    }
17383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    return image;
17483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine}
17583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
17625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turnervoid sanitizeOptions( AndroidOptions* opts )
17725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{
17883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    /* legacy support: we used to use -system <dir> and -image <file>
17983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine     * instead of -sysdir <dir> and -system <file>, so handle this by checking
18083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine     * whether the options point to directories or files.
18183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine     */
18283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    if (opts->image != NULL) {
18383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        if (opts->system != NULL) {
18483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            if (opts->sysdir != NULL) {
18583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                derror( "You can't use -sysdir, -system and -image at the same time.\n"
18683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                        "You should probably use '-sysdir <path> -system <file>'.\n" );
18783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                exit(2);
18883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            }
18983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        }
19083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        dwarning( "Please note that -image is obsolete and that -system is now used to point\n"
19183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                  "to the system image. Next time, try using '-sysdir <path> -system <file>' instead.\n" );
19283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        opts->sysdir = opts->system;
19383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        opts->system = opts->image;
19483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        opts->image  = NULL;
19583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    }
19683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    else if (opts->system != NULL && path_is_dir(opts->system)) {
19783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        if (opts->sysdir != NULL) {
19883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            derror( "Option -system should now be followed by a file path, not a directory one.\n"
19983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                    "Please use '-sysdir <path>' to point to the system directory.\n" );
20083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            exit(1);
20183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        }
20283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        dwarning( "Please note that the -system option should now be used to point to the initial\n"
20383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                  "system image (like the obsolete -image option). To point to the system directory\n"
20483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                  "please now use '-sysdir <path>' instead.\n" );
20583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
20683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        opts->sysdir = opts->system;
20783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        opts->system = NULL;
20883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    }
20983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
21025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (opts->nojni) {
21125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        opts->no_jni = opts->nojni;
21225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        opts->nojni  = 0;
21325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    }
21425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
21525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (opts->nocache) {
21625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        opts->no_cache = opts->nocache;
21725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        opts->nocache  = 0;
21825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    }
21925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
22025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (opts->noaudio) {
22125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        opts->no_audio = opts->noaudio;
22225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        opts->noaudio  = 0;
22325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    }
22425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
22525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (opts->noskin) {
22625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        opts->no_skin = opts->noskin;
22725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        opts->noskin  = 0;
22825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    }
22925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
23025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    /* If -no-cache is used, ignore any -cache argument */
23125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (opts->no_cache) {
23225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        opts->cache = 0;
23325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    }
23425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
23525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    /* the purpose of -no-audio is to disable sound output from the emulator,
23625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner     * not to disable Audio emulation. So simply force the 'none' backends */
23725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (opts->no_audio)
23825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        opts->audio = "none";
23925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
24025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    /* we don't accept -skindir without -skin now
24125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner     * to simplify the autoconfig stuff with virtual devices
24225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner     */
24325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (opts->no_skin) {
24425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        opts->skin    = "320x480";
24525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        opts->skindir = NULL;
24625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    }
24725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
24825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    if (opts->skindir) {
24925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        if (!opts->skin) {
25025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            derror( "the -skindir <path> option requires a -skin <name> option");
25125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner            exit(1);
25225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner        }
25325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    }
2540b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner
2550b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner    if (opts->bootchart) {
2560b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        char*  end;
2570b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        int    timeout = strtol(opts->bootchart, &end, 10);
2580b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        if (timeout == 0)
2590b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            opts->bootchart = NULL;
2600b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        else if (timeout < 0 || timeout > 15*60) {
2610b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            derror( "timeout specified for -bootchart option is invalid.\n"
2620b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner                    "please use integers between 1 and 900\n");
2630b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner            exit(1);
2640b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner        }
2650b0194940523fa3f318c380d0693907bd522241cDavid 'Digit' Turner    }
26625eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner}
26725eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
26825eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' TurnerAvdInfo* createAVD(AndroidOptions* opts, int* inAndroidBuild)
26925eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner{
27025eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    AvdInfo* ret = NULL;
27125eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    char   tmp[MAX_PATH];
27225eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    char*  tmpend = tmp + sizeof(tmp);
27325eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    char*  android_build_root = NULL;
27425eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner    char*  android_build_out  = NULL;
27525eb6557b94da066d6e137c07aeced39badf5aa6David 'Digit' Turner
27683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    /* If no AVD name was given, try to find the top of the
27783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine     * Android build tree
27883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine     */
27983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    if (opts->avd == NULL) {
28083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        do {
28183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            char*  out = getenv("ANDROID_PRODUCT_OUT");
28283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
28383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            if (out == NULL || out[0] == 0)
28483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                break;
28583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
28683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            if (!path_exists(out)) {
28783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                derror("Can't access ANDROID_PRODUCT_OUT as '%s'\n"
28883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                    "You need to build the Android system before launching the emulator",
28983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                    out);
29083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                exit(2);
29183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            }
29283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
2934bcc1d92f4d49ee7331bd2eacd28d497e505c5c7Jean-Baptiste Queru            android_build_root = getenv("ANDROID_BUILD_TOP");
2944bcc1d92f4d49ee7331bd2eacd28d497e505c5c7Jean-Baptiste Queru            if (android_build_root == NULL || android_build_root[0] == 0)
2954bcc1d92f4d49ee7331bd2eacd28d497e505c5c7Jean-Baptiste Queru                break;
2964bcc1d92f4d49ee7331bd2eacd28d497e505c5c7Jean-Baptiste Queru
2974bcc1d92f4d49ee7331bd2eacd28d497e505c5c7Jean-Baptiste Queru            if (!path_exists(android_build_root)) {
2984bcc1d92f4d49ee7331bd2eacd28d497e505c5c7Jean-Baptiste Queru                derror("Can't find the Android build root '%s'\n"
2994bcc1d92f4d49ee7331bd2eacd28d497e505c5c7Jean-Baptiste Queru                    "Please check the definition of the ANDROID_BUILD_TOP variable.\n"
3004bcc1d92f4d49ee7331bd2eacd28d497e505c5c7Jean-Baptiste Queru                    "It should point to the root of your source tree.\n",
3014bcc1d92f4d49ee7331bd2eacd28d497e505c5c7Jean-Baptiste Queru                    android_build_root );
30283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                exit(2);
30383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            }
30483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            android_build_out = out;
30583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            D( "found Android build root: %s", android_build_root );
30683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            D( "found Android build out:  %s", android_build_out );
30783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        } while (0);
30883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    }
30983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    /* if no virtual device name is given, and we're not in the
31083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine     * Android build system, we'll need to perform some auto-detection
31183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine     * magic :-)
31283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine     */
31383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    if (opts->avd == NULL && !android_build_out)
31483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    {
31583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        if (!opts->sysdir) {
31683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            opts->sysdir = _getSdkImagePath("system.img");
31783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            if (!opts->sysdir) {
31883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                derror(
31983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                "You did not specify a virtual device name, and the system\n"
32083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                "directory could not be found.\n\n"
32183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                "If you are an Android SDK user, please use '@<name>' or '-avd <name>'\n"
32283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                "to start a given virtual device (see -help-avd for details).\n\n"
32383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
32483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                "Otherwise, follow the instructions in -help-disk-images to start the emulator\n"
32583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                );
32683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                exit(2);
32783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            }
32883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            D("autoconfig: -sysdir %s", opts->sysdir);
32983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        }
33083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
33183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        if (!opts->system) {
33283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            opts->system = _getSdkSystemImage(opts->sysdir, "-image", "system.img");
333adc34fb9e9ad0700e9752ca67174c68925ca0c71David 'Digit' Turner            D("autoconfig: -system %s", opts->system);
33483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        }
33583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
33683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        if (!opts->kernel) {
33783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            opts->kernel = _getSdkSystemImage(opts->sysdir, "-kernel", "kernel-qemu");
33883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            D("autoconfig: -kernel %s", opts->kernel);
33983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        }
34083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
34183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        if (!opts->ramdisk) {
34283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            opts->ramdisk = _getSdkSystemImage(opts->sysdir, "-ramdisk", "ramdisk.img");
34383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            D("autoconfig: -ramdisk %s", opts->ramdisk);
34483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        }
34583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
34683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        /* if no data directory is specified, use the system directory */
34783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        if (!opts->datadir) {
34883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            opts->datadir   = android_strdup(opts->sysdir);
34983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            D("autoconfig: -datadir %s", opts->sysdir);
35083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        }
35183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
35283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        if (!opts->data) {
35383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            /* check for userdata-qemu.img in the data directory */
35483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            bufprint(tmp, tmpend, "%s/userdata-qemu.img", opts->datadir);
35583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            if (!path_exists(tmp)) {
35683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                derror(
35783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                "You did not provide the name of an Android Virtual Device\n"
35883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                "with the '-avd <name>' option. Read -help-avd for more information.\n\n"
35983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
36083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                "If you *really* want to *NOT* run an AVD, consider using '-data <file>'\n"
36183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                "to specify a data partition image file (I hope you know what you're doing).\n"
36283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                );
36383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                exit(2);
36483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            }
36583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
36683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            opts->data = android_strdup(tmp);
36783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            D("autoconfig: -data %s", opts->data);
36883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        }
36983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
37083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        if (!opts->snapstorage && opts->datadir) {
37183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            bufprint(tmp, tmpend, "%s/snapshots.img", opts->datadir);
37283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            if (path_exists(tmp)) {
37383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                opts->snapstorage = android_strdup(tmp);
37483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                D("autoconfig: -snapstorage %s", opts->snapstorage);
37583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            }
37683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        }
37783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    }
37883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
37983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    /* setup the virtual device differently depending on whether
38083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine     * we are in the Android build system or not
38183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine     */
38283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    if (opts->avd != NULL)
38383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    {
38483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        ret = avdInfo_new( opts->avd, android_avdParams );
38583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        if (ret == NULL) {
38683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            /* an error message has already been printed */
38783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            dprint("could not find virtual device named '%s'", opts->avd);
38883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            exit(1);
38983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        }
39083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    }
39183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    else
39283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    {
39383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        if (!android_build_out) {
39483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            android_build_out = android_build_root = opts->sysdir;
39583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        }
39683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        ret = avdInfo_newForAndroidBuild(
39783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                            android_build_root,
39883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                            android_build_out,
39983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine                            android_avdParams );
40083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
40183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        if(ret == NULL) {
40283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            D("could not start virtual device\n");
40383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine            exit(1);
40483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        }
40583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    }
40683ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
40783ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    if (android_build_out) {
40883ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        *inAndroidBuild = 1;
40983ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    } else {
41083ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine        *inAndroidBuild = 0;
41183ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    }
41283ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
41383ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine    return ret;
41483ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine}
41583ffd66e78d290aa054ace5e484ae3766f638390Vladimir Chtchetkine
416bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turnervoid handle_ui_options( AndroidOptions* opts )
417bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner{
418bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner    return;
419bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner}
420bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner
421bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turnerint attach_ui_to_core( AndroidOptions* opts )
422bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner{
423bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner    return 0;
424bdb6f2dd35a4c749186e665d55d7b76375d7e71dDavid 'Digit' Turner}
425