Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ShadowNinja committed Dec 7, 2015
1 parent 51e8c2b commit ea2964f
Show file tree
Hide file tree
Showing 8 changed files with 121 additions and 33 deletions.
2 changes: 1 addition & 1 deletion src/clientmedia.cpp
Expand Up @@ -34,7 +34,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,

static std::string getMediaCacheDir()
{
return porting::path_user + DIR_DELIM + "cache" + DIR_DELIM + "media";
return porting::path_cache + DIR_DELIM + "media";
}

/*
Expand Down
5 changes: 5 additions & 0 deletions src/filesys.cpp
Expand Up @@ -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

2 changes: 2 additions & 0 deletions src/filesys.h
Expand Up @@ -115,6 +115,8 @@ const char *GetFilenameFromPath(const char *path);

bool safeWriteToFile(const std::string &path, const std::string &content);

bool Rename(const std::string &from, const std::string &to);

} // namespace fs

#endif
Expand Down
12 changes: 6 additions & 6 deletions src/main.cpp
Expand Up @@ -164,7 +164,13 @@ int main(int argc, char *argv[])
setup_log_params(cmd_args);

porting::signal_handler_init();

#ifdef __ANDROID__
porting::initAndroid();
porting::initializePathsAndroid();
#else
porting::initializePaths();
#endif

if (!create_userdata_path()) {
errorstream << "Cannot create user data directory" << std::endl;
Expand Down Expand Up @@ -422,9 +428,6 @@ static bool create_userdata_path()
bool success;

#ifdef __ANDROID__
porting::initAndroid();

porting::setExternalStorageDir(porting::jnienv);
if (!fs::PathExists(porting::path_user)) {
success = fs::CreateDir(porting::path_user);
} else {
Expand All @@ -436,9 +439,6 @@ static bool create_userdata_path()
success = fs::CreateDir(porting::path_user);
#endif

infostream << "path_share = " << porting::path_share << std::endl;
infostream << "path_user = " << porting::path_user << std::endl;

return success;
}

Expand Down
38 changes: 37 additions & 1 deletion src/porting.cpp
Expand Up @@ -139,6 +139,7 @@ void signal_handler_init(void)
std::string path_share = "..";
std::string path_user = "..";
std::string path_locale = path_share + DIR_DELIM + "locale";
std::string path_cache = path_user + DIR_DELIM + "cache";


std::string getDataPath(const char *subpath)
Expand Down Expand Up @@ -463,6 +464,25 @@ bool setSystemPaths()

#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()
{
Expand Down Expand Up @@ -513,10 +533,27 @@ void initializePaths()
if (!setSystemPaths())
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

infostream << "Detected share path: " << path_share << std::endl;
infostream << "Detected user path: " << path_user << std::endl;
infostream << "Detected cache path: " << path_cache << std::endl;

bool found_localedir = false;
#ifdef STATIC_LOCALEDIR
Expand All @@ -542,7 +579,6 @@ void initializePaths()
if (!found_localedir) {
errorstream << "Couldn't find a locale directory!" << std::endl;
}

}


Expand Down
11 changes: 11 additions & 0 deletions src/porting.h
Expand Up @@ -147,12 +147,23 @@ extern std::string path_user;
*/
extern std::string path_locale;

/*
Path to directory for storing caches.
*/
extern std::string path_cache;

/*
Get full path of stuff in data directory.
Example: "stone.png" -> "../data/stone.png"
*/
std::string getDataPath(const char *subpath);

/*
Move cache folder from path_user to the
system cache location if possible.
*/
void migrateCachePath();

/*
Initialize path_*.
*/
Expand Down
78 changes: 56 additions & 22 deletions src/porting_android.cpp
Expand Up @@ -164,29 +164,63 @@ void cleanupAndroid()
jvm->DetachCurrentThread();
}

void setExternalStorageDir(JNIEnv* lJNIEnv)
static std::string javaStringToUTF8(jstring js)
{
// Android: Retrieve ablsolute path to external storage device (sdcard)
jclass ClassEnv = lJNIEnv->FindClass("android/os/Environment");
jmethodID MethodDir =
lJNIEnv->GetStaticMethodID(ClassEnv,
"getExternalStorageDirectory","()Ljava/io/File;");
jobject ObjectFile = lJNIEnv->CallStaticObjectMethod(ClassEnv, MethodDir);
jclass ClassFile = lJNIEnv->FindClass("java/io/File");

jmethodID MethodPath =
lJNIEnv->GetMethodID(ClassFile, "getAbsolutePath",
"()Ljava/lang/String;");
jstring StringPath =
(jstring) lJNIEnv->CallObjectMethod(ObjectFile, MethodPath);

const char *externalPath = lJNIEnv->GetStringUTFChars(StringPath, NULL);
std::string userPath(externalPath);
lJNIEnv->ReleaseStringUTFChars(StringPath, externalPath);

path_storage = userPath;
path_user = userPath + DIR_DELIM + PROJECT_NAME_C;
path_share = userPath + DIR_DELIM + PROJECT_NAME_C;
std::string str;
// Get string as a UTF-8 c-string
const char *c_str = jnienv->GetStringUTFChars(js, NULL);
// Save it
str = c_str;
// And free the c-string
jnienv->ReleaseStringUTFChars(js, c_str);
return str;
}

// Calls static method if obj is NULL
static std::string getAndroidPath(jclass cls, jobject obj, jclass cls_File,
jmethodID mt_getAbsPath, const char *getter)
{
// 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;");

// Call getter
jobject ob_file;
if (obj)
ob_file = jnienv->CallObjectMethod(obj, mt_getter);
else
ob_file = jnienv->CallStaticObjectMethod(cls, mt_getter);

// Call getAbsolutePath
jstring js_path = (jstring) jnienv->CallObjectMethod(ob_file,
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,
Expand Down
6 changes: 3 additions & 3 deletions src/porting_android.h
Expand Up @@ -43,10 +43,10 @@ void initAndroid();
void cleanupAndroid();

/**
* set storage dir on external sdcard#
* @param lJNIEnv environment from android
* Initializes path_* variables for Android
* @param env Android JNI environment
*/
void setExternalStorageDir(JNIEnv* lJNIEnv);
void initializePathsAndroid();

/**
* use java function to copy media from assets to external storage
Expand Down

0 comments on commit ea2964f

Please sign in to comment.