Add seperate cache path

This is set to the XDG cache path where possible.
It's set to the app's cache path on Android.
This commit is contained in:
ShadowNinja 2015-08-24 17:00:06 -04:00
parent 51e8c2b277
commit ea2964f5a1
8 changed files with 118 additions and 30 deletions

@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
static std::string getMediaCacheDir() static std::string getMediaCacheDir()
{ {
return porting::path_user + DIR_DELIM + "cache" + DIR_DELIM + "media"; return porting::path_cache + DIR_DELIM + "media";
} }
/* /*

@ -707,5 +707,10 @@ bool safeWriteToFile(const std::string &path, const std::string &content)
} }
} }
bool Rename(const std::string &from, const std::string &to)
{
return rename(from.c_str(), to.c_str()) == 0;
}
} // namespace fs } // namespace fs

@ -115,6 +115,8 @@ const char *GetFilenameFromPath(const char *path);
bool safeWriteToFile(const std::string &path, const std::string &content); bool safeWriteToFile(const std::string &path, const std::string &content);
bool Rename(const std::string &from, const std::string &to);
} // namespace fs } // namespace fs
#endif #endif

@ -164,7 +164,13 @@ int main(int argc, char *argv[])
setup_log_params(cmd_args); setup_log_params(cmd_args);
porting::signal_handler_init(); porting::signal_handler_init();
#ifdef __ANDROID__
porting::initAndroid();
porting::initializePathsAndroid();
#else
porting::initializePaths(); porting::initializePaths();
#endif
if (!create_userdata_path()) { if (!create_userdata_path()) {
errorstream << "Cannot create user data directory" << std::endl; errorstream << "Cannot create user data directory" << std::endl;
@ -422,9 +428,6 @@ static bool create_userdata_path()
bool success; bool success;
#ifdef __ANDROID__ #ifdef __ANDROID__
porting::initAndroid();
porting::setExternalStorageDir(porting::jnienv);
if (!fs::PathExists(porting::path_user)) { if (!fs::PathExists(porting::path_user)) {
success = fs::CreateDir(porting::path_user); success = fs::CreateDir(porting::path_user);
} else { } else {
@ -436,9 +439,6 @@ static bool create_userdata_path()
success = fs::CreateDir(porting::path_user); success = fs::CreateDir(porting::path_user);
#endif #endif
infostream << "path_share = " << porting::path_share << std::endl;
infostream << "path_user = " << porting::path_user << std::endl;
return success; return success;
} }

@ -139,6 +139,7 @@ void signal_handler_init(void)
std::string path_share = ".."; std::string path_share = "..";
std::string path_user = ".."; std::string path_user = "..";
std::string path_locale = path_share + DIR_DELIM + "locale"; std::string path_locale = path_share + DIR_DELIM + "locale";
std::string path_cache = path_user + DIR_DELIM + "cache";
std::string getDataPath(const char *subpath) std::string getDataPath(const char *subpath)
@ -463,6 +464,25 @@ bool setSystemPaths()
#endif #endif
void migrateCachePath()
{
const std::string local_cache_path = path_user + DIR_DELIM + "cache";
// Delete tmp folder if it exists (it only ever contained
// a temporary ogg file, which is no longer used).
if (fs::PathExists(local_cache_path + DIR_DELIM + "tmp"))
fs::RecursiveDelete(local_cache_path + DIR_DELIM + "tmp");
// Bail if migration impossible
if (path_cache == local_cache_path || !fs::PathExists(local_cache_path)
|| fs::PathExists(path_cache)) {
return;
}
if (!fs::Rename(local_cache_path, path_cache)) {
errorstream << "Failed to migrate local cache path "
"to system path!" << std::endl;
}
}
void initializePaths() void initializePaths()
{ {
@ -513,10 +533,27 @@ void initializePaths()
if (!setSystemPaths()) if (!setSystemPaths())
errorstream << "Failed to get one or more system-wide path" << std::endl; errorstream << "Failed to get one or more system-wide path" << std::endl;
// Initialize path_cache
// First try $XDG_CACHE_HOME/PROJECT_NAME
const char *cache_dir = getenv("XDG_CACHE_HOME");
if (cache_dir) {
path_cache = std::string(cache_dir) + DIR_DELIM + PROJECT_NAME;
} else {
// Then try $HOME/.cache/PROJECT_NAME
const char *home_dir = getenv("HOME");
if (home_dir) {
path_cache = std::string(home_dir) + DIR_DELIM + ".cache"
+ DIR_DELIM + PROJECT_NAME;
}
// If neither works, leave it at $PATH_USER/cache
}
// Migrate cache folder to new location if possible
migrateCachePath();
#endif #endif
infostream << "Detected share path: " << path_share << std::endl; infostream << "Detected share path: " << path_share << std::endl;
infostream << "Detected user path: " << path_user << std::endl; infostream << "Detected user path: " << path_user << std::endl;
infostream << "Detected cache path: " << path_cache << std::endl;
bool found_localedir = false; bool found_localedir = false;
#ifdef STATIC_LOCALEDIR #ifdef STATIC_LOCALEDIR
@ -542,7 +579,6 @@ void initializePaths()
if (!found_localedir) { if (!found_localedir) {
errorstream << "Couldn't find a locale directory!" << std::endl; errorstream << "Couldn't find a locale directory!" << std::endl;
} }
} }

@ -147,12 +147,23 @@ extern std::string path_user;
*/ */
extern std::string path_locale; extern std::string path_locale;
/*
Path to directory for storing caches.
*/
extern std::string path_cache;
/* /*
Get full path of stuff in data directory. Get full path of stuff in data directory.
Example: "stone.png" -> "../data/stone.png" Example: "stone.png" -> "../data/stone.png"
*/ */
std::string getDataPath(const char *subpath); std::string getDataPath(const char *subpath);
/*
Move cache folder from path_user to the
system cache location if possible.
*/
void migrateCachePath();
/* /*
Initialize path_*. Initialize path_*.
*/ */

@ -164,29 +164,63 @@ void cleanupAndroid()
jvm->DetachCurrentThread(); jvm->DetachCurrentThread();
} }
void setExternalStorageDir(JNIEnv* lJNIEnv) static std::string javaStringToUTF8(jstring js)
{ {
// Android: Retrieve ablsolute path to external storage device (sdcard) std::string str;
jclass ClassEnv = lJNIEnv->FindClass("android/os/Environment"); // Get string as a UTF-8 c-string
jmethodID MethodDir = const char *c_str = jnienv->GetStringUTFChars(js, NULL);
lJNIEnv->GetStaticMethodID(ClassEnv, // Save it
"getExternalStorageDirectory","()Ljava/io/File;"); str = c_str;
jobject ObjectFile = lJNIEnv->CallStaticObjectMethod(ClassEnv, MethodDir); // And free the c-string
jclass ClassFile = lJNIEnv->FindClass("java/io/File"); jnienv->ReleaseStringUTFChars(js, c_str);
return str;
}
jmethodID MethodPath = // Calls static method if obj is NULL
lJNIEnv->GetMethodID(ClassFile, "getAbsolutePath", static std::string getAndroidPath(jclass cls, jobject obj, jclass cls_File,
"()Ljava/lang/String;"); jmethodID mt_getAbsPath, const char *getter)
jstring StringPath = {
(jstring) lJNIEnv->CallObjectMethod(ObjectFile, MethodPath); // Get getter method
jmethodID mt_getter;
if (obj)
mt_getter = jnienv->GetMethodID(cls, getter,
"()Ljava/io/File;");
else
mt_getter = jnienv->GetStaticMethodID(cls, getter,
"()Ljava/io/File;");
const char *externalPath = lJNIEnv->GetStringUTFChars(StringPath, NULL); // Call getter
std::string userPath(externalPath); jobject ob_file;
lJNIEnv->ReleaseStringUTFChars(StringPath, externalPath); if (obj)
ob_file = jnienv->CallObjectMethod(obj, mt_getter);
else
ob_file = jnienv->CallStaticObjectMethod(cls, mt_getter);
path_storage = userPath; // Call getAbsolutePath
path_user = userPath + DIR_DELIM + PROJECT_NAME_C; jstring js_path = (jstring) jnienv->CallObjectMethod(ob_file,
path_share = userPath + DIR_DELIM + PROJECT_NAME_C; mt_getAbsPath);
return javaStringToUTF8(js_path);
}
void initializePathsAndroid()
{
// Get Environment class
jclass cls_Env = jnienv->FindClass("android/os/Environment");
// Get File class
jclass cls_File = jnienv->FindClass("java/io/File");
// Get getAbsolutePath method
jmethodID mt_getAbsPath = jnienv->GetMethodID(cls_File,
"getAbsolutePath", "()Ljava/lang/String;");
path_cache = getAndroidPath(nativeActivity, app_global->activity->clazz,
cls_File, mt_getAbsPath, "getCacheDir");
path_storage = getAndroidPath(cls_Env, NULL, cls_File, mt_getAbsPath,
"getExternalStorageDirectory");
path_user = path_storage + DIR_DELIM + PROJECT_NAME_C;
path_share = path_storage + DIR_DELIM + PROJECT_NAME_C;
migrateCachePath();
} }
void showInputDialog(const std::string& acceptButton, const std::string& hint, void showInputDialog(const std::string& acceptButton, const std::string& hint,

@ -43,10 +43,10 @@ void initAndroid();
void cleanupAndroid(); void cleanupAndroid();
/** /**
* set storage dir on external sdcard# * Initializes path_* variables for Android
* @param lJNIEnv environment from android * @param env Android JNI environment
*/ */
void setExternalStorageDir(JNIEnv* lJNIEnv); void initializePathsAndroid();
/** /**
* use java function to copy media from assets to external storage * use java function to copy media from assets to external storage