18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Copyright (C) 2009 The Android Open Source Project
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This software is licensed under the terms of the GNU General Public
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** License version 2, as published by the Free Software Foundation, and
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** may be copied, distributed, and modified under those terms.
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project**
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** This program is distributed in the hope that it will be useful,
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** but WITHOUT ANY WARRANTY; without even the implied warranty of
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project** GNU General Public License for more details.
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project*/
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/user-config.h"
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/bufprint.h"
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/debug.h"
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/system.h"
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "android/utils/path.h"
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <errno.h>
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <sys/time.h>
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  D(...)   VERBOSE_PRINT(init,__VA_ARGS__)
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if 0 /* set to 1 for more debugging */
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define  DD(...)  D(__VA_ARGS__)
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define  DD(...)  ((void)0)
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstruct AUserConfig {
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ABool      changed;
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int        windowX;
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int        windowY;
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t   uuid;
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*      iniPath;
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Name of the user-config file */
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  USER_CONFIG_FILE  "emulator-user.ini"
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  KEY_WINDOW_X  "window.x"
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  KEY_WINDOW_Y  "window.y"
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  KEY_UUID      "uuid"
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  DEFAULT_X  100
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define  DEFAULT_Y  100
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Create a new AUserConfig object from a given AvdInfo */
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectAUserConfig*
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectauserConfig_new( AvdInfo*  info )
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    AUserConfig*  uc;
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char          inAndroidBuild = avdInfo_inAndroidBuild(info);
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char          needUUID = 1;
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char          temp[PATH_MAX], *p=temp, *end=p+sizeof(temp);
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char*         parentPath;
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    IniFile*      ini = NULL;
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ANEW0(uc);
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* If we are in the Android build system, store the configuration
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * in ~/.android/emulator-user.ini. otherwise, store it in the file
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * emulator-user.ini in the AVD's content directory.
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     */
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (inAndroidBuild) {
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p = bufprint_config_file(temp, end, USER_CONFIG_FILE);
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
67c005246ed03de874fdc432073ba8e5e8ebfed922David 'Digit' Turner        p = bufprint(temp, end, "%s/%s", avdInfo_getContentPath(info),
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     USER_CONFIG_FILE);
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* handle the unexpected */
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (p >= end) {
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Hmmm, something is weird, let's use a temporary file instead */
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p = bufprint_temp_file(temp, end, USER_CONFIG_FILE);
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (p >= end) {
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            derror("Weird: Cannot create temporary user-config file?");
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(2);
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dwarning("Weird: Content path too long, using temporary user-config.");
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uc->iniPath = ASTRDUP(temp);
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DD("looking user-config in: %s", uc->iniPath);
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* ensure that the parent directory exists */
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    parentPath = path_parent(uc->iniPath, 1);
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (parentPath == NULL) {
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        derror("Weird: Can't find parent of user-config file: %s",
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               uc->iniPath);
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(2);
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!path_exists(parentPath)) {
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!inAndroidBuild) {
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            derror("Weird: No content path for this AVD: %s", parentPath);
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(2);
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        DD("creating missing directory: %s", parentPath);
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (path_mkdir_if_needed(parentPath, 0755) < 0) {
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            derror("Using empty user-config, can't create %s: %s",
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   parentPath, strerror(errno));
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            exit(2);
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (path_exists(uc->iniPath)) {
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        DD("reading user-config file");
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        ini = iniFile_newFromFile(uc->iniPath);
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ini == NULL) {
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dwarning("Can't read user-config file: %s\nUsing default values",
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     uc->iniPath);
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ini != NULL) {
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uc->windowX = iniFile_getInteger(ini, KEY_WINDOW_X, DEFAULT_X);
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        DD("    found %s = %d", KEY_WINDOW_X, uc->windowX);
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uc->windowY = iniFile_getInteger(ini, KEY_WINDOW_Y, DEFAULT_Y);
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        DD("    found %s = %d", KEY_WINDOW_Y, uc->windowY);
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (iniFile_getValue(ini, KEY_UUID) != NULL) {
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            uc->uuid = (uint64_t) iniFile_getInt64(ini, KEY_UUID, 0LL);
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            needUUID = 0;
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            DD("    found %s = %lld", KEY_UUID, uc->uuid);
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        iniFile_free(ini);
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else {
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uc->windowX = DEFAULT_X;
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uc->windowY = DEFAULT_Y;
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uc->changed = 1;
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Generate a 64-bit UUID if necessary. We simply take the
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     * current time, which avoids any privacy-related value.
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     */
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (needUUID) {
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        struct timeval  tm;
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        gettimeofday( &tm, NULL );
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uc->uuid    = (uint64_t)tm.tv_sec*1000 + tm.tv_usec/1000;
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uc->changed = 1;
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        DD("    Generated UUID = %lld", uc->uuid);
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return uc;
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectuint64_t
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectauserConfig_getUUID( AUserConfig*  uconfig )
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return uconfig->uuid;
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectauserConfig_getWindowPos( AUserConfig*  uconfig, int  *pX, int  *pY )
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *pX = uconfig->windowX;
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *pY = uconfig->windowY;
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectauserConfig_setWindowPos( AUserConfig*  uconfig, int  x, int  y )
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (x != uconfig->windowX || y != uconfig->windowY) {
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uconfig->windowX = x;
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uconfig->windowY = y;
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        uconfig->changed = 1;
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Save the user configuration back to the content directory.
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Should be used in an atexit() handler */
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source ProjectauserConfig_save( AUserConfig*  uconfig )
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    IniFile*   ini;
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char       temp[256];
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (uconfig->changed == 0) {
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        D("User-config was not changed.");
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    bufprint(temp, temp+sizeof(temp),
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             "%s = %d\n"
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             "%s = %d\n"
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             "%s = %lld\n",
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             KEY_WINDOW_X, uconfig->windowX,
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             KEY_WINDOW_Y, uconfig->windowY,
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             KEY_UUID,     uconfig->uuid );
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    DD("Generated user-config file:\n%s", temp);
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ini = iniFile_newFromMemory(temp, uconfig->iniPath);
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ini == NULL) {
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        D("Weird: can't create user-config iniFile?");
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (iniFile_saveToFile(ini, uconfig->iniPath) < 0) {
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        dwarning("could not save user configuration: %s: %s",
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 uconfig->iniPath, strerror(errno));
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        D("User configuration saved to %s", uconfig->iniPath);
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    iniFile_free(ini);
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
213