Hash :
a481bee2
Author :
Date :
2020-11-04T18:20:24
Add GetEnvironmentVarOrUnCachedAndroidProperty GetEnvironmentVarOrAndroidProperty will first return the given variableName from the processes enviroment if defined. If not defined and running on Android, will look up the corresponding property and store it in the environment. The framecapture code wants to see when the Android property changes so add an uncached version of GetEnvironmentVarOrAndroidProperty that always does the getprop command (which can be time consuming). Bug: b/170328907 Change-Id: I0624c0646889435cb6f6eb20a6d3cceb6ae3eb48 Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/2520107 Reviewed-by: Jamie Madill <jmadill@chromium.org> Reviewed-by: Ian Elliott <ianelliott@google.com> Reviewed-by: Cody Northrop <cnorthrop@google.com> Commit-Queue: Courtney Goeltzenleuchter <courtneygo@google.com>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
//
// Copyright 2018 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// system_utils.cpp: Implementation of common functions
#include "common/system_utils.h"
#include <stdlib.h>
namespace angle
{
std::string GetExecutableName()
{
#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 21
// Support for "getprogname" function in bionic was introduced in L (API level 21)
const char *executableName = getprogname();
return (executableName) ? std::string(executableName) : "ANGLE";
#else
std::string executableName = GetExecutablePath();
size_t lastPathSepLoc = executableName.find_last_of(GetPathSeparator());
return (lastPathSepLoc > 0 ? executableName.substr(lastPathSepLoc + 1, executableName.length())
: "ANGLE");
#endif // ANGLE_PLATFORM_ANDROID
}
// On Android return value cached in the process environment, if none, call
// GetEnvironmentVarOrUnCachedAndroidProperty if not in environment.
std::string GetEnvironmentVarOrAndroidProperty(const char *variableName, const char *propertyName)
{
#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 21
// Can't use GetEnvironmentVar here because that won't allow us to distinguish between the
// environment being set to an empty string vs. not set at all.
const char *variableValue = getenv(variableName);
if (variableValue != nullptr)
{
std::string value(variableValue);
return value;
}
#endif
return GetEnvironmentVarOrUnCachedAndroidProperty(variableName, propertyName);
}
// Call out to 'getprop' on a shell to get an Android property. If the value was set, set an
// environment variable with that value. Return the value of the environment variable.
std::string GetEnvironmentVarOrUnCachedAndroidProperty(const char *variableName,
const char *propertyName)
{
#if defined(ANGLE_PLATFORM_ANDROID) && __ANDROID_API__ >= 21
std::string sanitizedPropertyName = propertyName;
sanitizedPropertyName.erase(
std::remove(sanitizedPropertyName.begin(), sanitizedPropertyName.end(), '\''),
sanitizedPropertyName.end());
std::string command("getprop '");
command += sanitizedPropertyName;
command += "'";
// Run the command and open a I/O stream to read the value
constexpr int kStreamSize = 64;
char stream[kStreamSize] = {};
FILE *pipe = popen(command.c_str(), "r");
if (pipe != nullptr)
{
fgets(stream, kStreamSize, pipe);
pclose(pipe);
}
// Right strip white space
std::string value(stream);
value.erase(value.find_last_not_of(" \n\r\t") + 1);
// Set the environment variable with the value.
SetEnvironmentVar(variableName, value.c_str());
return value;
#endif // ANGLE_PLATFORM_ANDROID
// Return the environment variable's value.
return GetEnvironmentVar(variableName);
}
bool PrependPathToEnvironmentVar(const char *variableName, const char *path)
{
std::string oldValue = GetEnvironmentVar(variableName);
const char *newValue = nullptr;
std::string buf;
if (oldValue.empty())
{
newValue = path;
}
else
{
buf = path;
buf += GetPathSeparatorForEnvironmentVar();
buf += oldValue;
newValue = buf.c_str();
}
return SetEnvironmentVar(variableName, newValue);
}
} // namespace angle