util: Add property_get() fallback for android
Environment variables aren't the easiest thing to use on android. So add a fallback to android's property mechanism for os_get_option(). This is slightly complicated by the fact that the assumption that the return value of os_get_option() need not be freed. Signed-off-by: Rob Clark <robdclark@chromium.org> Reviewed-by: Eric Anholt <eric@anholt.net> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/7763>
This commit is contained in:
parent
73c6899285
commit
eeecc21d93
|
@ -56,6 +56,7 @@
|
||||||
# define LOG_TAG "MESA"
|
# define LOG_TAG "MESA"
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
# include <log/log.h>
|
# include <log/log.h>
|
||||||
|
# include <cutils/properties.h>
|
||||||
#elif DETECT_OS_LINUX || DETECT_OS_CYGWIN || DETECT_OS_SOLARIS || DETECT_OS_HURD
|
#elif DETECT_OS_LINUX || DETECT_OS_CYGWIN || DETECT_OS_SOLARIS || DETECT_OS_HURD
|
||||||
# include <unistd.h>
|
# include <unistd.h>
|
||||||
#elif DETECT_OS_OPENBSD || DETECT_OS_FREEBSD
|
#elif DETECT_OS_OPENBSD || DETECT_OS_FREEBSD
|
||||||
|
@ -121,16 +122,100 @@ os_log_message(const char *message)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DETECT_OS_ANDROID
|
||||||
|
# include <ctype.h>
|
||||||
|
# include "hash_table.h"
|
||||||
|
# include "ralloc.h"
|
||||||
|
# include "simple_mtx.h"
|
||||||
|
|
||||||
|
static struct hash_table *options_tbl;
|
||||||
|
static simple_mtx_t options_tbl_lock = _SIMPLE_MTX_INITIALIZER_NP;
|
||||||
|
|
||||||
|
static void
|
||||||
|
options_tbl_fini(void)
|
||||||
|
{
|
||||||
|
_mesa_hash_table_destroy(options_tbl, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an option value from android's property system, as a fallback to
|
||||||
|
* getenv() (which is generally less useful on android due to processes
|
||||||
|
* typically being forked from the zygote.
|
||||||
|
*
|
||||||
|
* The option name used for getenv is translated into a property name
|
||||||
|
* by:
|
||||||
|
*
|
||||||
|
* 1) convert to lowercase
|
||||||
|
* 2) replace '_' with '.'
|
||||||
|
* 3) if necessary, prepend "mesa."
|
||||||
|
*
|
||||||
|
* For example:
|
||||||
|
* - MESA_EXTENSION_OVERRIDE -> mesa.extension.override
|
||||||
|
* - GALLIUM_HUD -> mesa.gallium.hud
|
||||||
|
*
|
||||||
|
* Note that we use a hashtable for two purposes:
|
||||||
|
* 1) Avoid re-translating the option name on subsequent lookups
|
||||||
|
* 2) Avoid leaking memory. Because property_get() returns the
|
||||||
|
* property value into a user allocated buffer, we cannot return
|
||||||
|
* that directly to the caller, so we need to strdup(). With the
|
||||||
|
* hashtable, subsquent lookups can return the existing string.
|
||||||
|
*/
|
||||||
|
static const char *
|
||||||
|
os_get_android_option(const char *name)
|
||||||
|
{
|
||||||
|
if (!options_tbl) {
|
||||||
|
options_tbl = _mesa_hash_table_create(NULL, _mesa_hash_string,
|
||||||
|
_mesa_key_string_equal);
|
||||||
|
atexit(options_tbl_fini);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct hash_entry *entry = _mesa_hash_table_search(options_tbl, name);
|
||||||
|
if (entry) {
|
||||||
|
return entry->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
char value[PROPERTY_VALUE_MAX];
|
||||||
|
char key[PROPERTY_KEY_MAX];
|
||||||
|
char *p = key, *end = key + PROPERTY_KEY_MAX;
|
||||||
|
/* add "mesa." prefix if necessary: */
|
||||||
|
if (strstr(name, "MESA_") != name)
|
||||||
|
p += strlcpy(p, "mesa.", end - p);
|
||||||
|
p += strlcpy(p, name, end - p);
|
||||||
|
for (int i = 0; key[i]; i++) {
|
||||||
|
if (key[i] == '_') {
|
||||||
|
key[i] = '.';
|
||||||
|
} else {
|
||||||
|
key[i] = tolower(key[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *opt = NULL;
|
||||||
|
int len = property_get(key, value, NULL);
|
||||||
|
if (len > 1) {
|
||||||
|
opt = ralloc_strdup(options_tbl, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
_mesa_hash_table_insert(options_tbl, name, value);
|
||||||
|
|
||||||
|
return opt;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if !defined(EMBEDDED_DEVICE)
|
#if !defined(EMBEDDED_DEVICE)
|
||||||
const char *
|
const char *
|
||||||
os_get_option(const char *name)
|
os_get_option(const char *name)
|
||||||
{
|
{
|
||||||
return getenv(name);
|
const char *opt = getenv(name);
|
||||||
|
#if DETECT_OS_ANDROID
|
||||||
|
if (!opt) {
|
||||||
|
opt = os_get_android_option(name);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return opt;
|
||||||
}
|
}
|
||||||
#endif /* !EMBEDDED_DEVICE */
|
#endif /* !EMBEDDED_DEVICE */
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the size of the total physical memory.
|
* Return the size of the total physical memory.
|
||||||
* \param size returns the size of the total physical memory
|
* \param size returns the size of the total physical memory
|
||||||
|
|
Loading…
Reference in New Issue