Choose a directory where we have the most available disk space for data extraction.

It's not a perfect solution because at least on my device internal storage is much faster than sd card. But at least it should be much safer to choose a path with more free space.
This commit is contained in:
Deve
2017-02-03 23:32:50 +01:00
parent 01765fce80
commit 7c48c3e6cc
2 changed files with 66 additions and 0 deletions

View File

@@ -27,6 +27,7 @@
#ifdef ANDROID
#include <android/asset_manager.h>
#include <sys/statfs.h>
#endif
//-----------------------------------------------------------------------------
@@ -96,6 +97,25 @@ void AssetsAndroid::init()
// Create data dir if it's not available anywhere
if (m_stk_dir.size() == 0)
{
std::string preferred_path = getPreferredPath(paths);
if (preferred_path.length() > 0)
{
if (m_file_manager->checkAndCreateDirectoryP(preferred_path +
"/stk/data"))
{
Log::info("AssetsAndroid", "Data directory created in: %s",
preferred_path.c_str());
m_stk_dir = preferred_path + "/stk";
needs_extract_data = true;
}
}
}
// If getPreferredPath failed for some reason, then try to use the first
// available path
if (m_stk_dir.size() == 0)
{
for (std::string path : paths)
{
@@ -431,3 +451,48 @@ void AssetsAndroid::touchFile(std::string path)
}
//-----------------------------------------------------------------------------
/** Determines best path for extracting assets, depending on available disk
* space.
* \param paths A list of paths that should be checked
* \return Best path or empty string in case of error
*/
std::string AssetsAndroid::getPreferredPath(const std::vector<std::string>&
paths)
{
#ifdef ANDROID
std::string preferred_path;
int prev_available_space = 0;
for (std::string path : paths)
{
// Paths that start with /data should be used only as a fallback if
// everything other doesn't work, because typical user doesn't have
// access to these directories and i.e. can't manually delete the files
// to clean up device
if (path.find("/data") == 0)
continue;
struct statfs stat;
if (statfs(path.c_str(), &stat) != 0)
continue;
int available_space = (int)((stat.f_bavail * stat.f_bsize) / 1000000);
Log::info("AssetsAndroid", "Available space in '%s': %i MB",
path.c_str(), available_space);
if (available_space > prev_available_space)
{
preferred_path = path;
prev_available_space = available_space;
}
}
return preferred_path;
#endif
return "";
}
//-----------------------------------------------------------------------------

View File

@@ -32,6 +32,7 @@ private:
bool extractDir(std::string dir_name);
void removeData();
void touchFile(std::string path);
std::string getPreferredPath(const std::vector<std::string>& paths);
public:
AssetsAndroid(FileManager* file_manager);