Kaynağa Gözat

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.
ShadowNinja 8 yıl önce
ebeveyn
işleme
ea2964f5a1
8 değiştirilmiş dosya ile 121 ekleme ve 33 silme
  1. 1 1
      src/clientmedia.cpp
  2. 5 0
      src/filesys.cpp
  3. 2 0
      src/filesys.h
  4. 6 6
      src/main.cpp
  5. 37 1
      src/porting.cpp
  6. 11 0
      src/porting.h
  7. 56 22
      src/porting_android.cpp
  8. 3 3
      src/porting_android.h

+ 1 - 1
src/clientmedia.cpp

@@ -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";
 }
 
 /*

+ 5 - 0
src/filesys.cpp

@@ -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 - 0
src/filesys.h

@@ -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

+ 6 - 6
src/main.cpp

@@ -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;
@@ -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 {
@@ -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;
 }
 

+ 37 - 1
src/porting.cpp

@@ -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)
@@ -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()
 {
@@ -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
@@ -542,7 +579,6 @@ void initializePaths()
 	if (!found_localedir) {
 		errorstream << "Couldn't find a locale directory!" << std::endl;
 	}
-
 }
 
 

+ 11 - 0
src/porting.h

@@ -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_*.
 */

+ 56 - 22
src/porting_android.cpp

@@ -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,

+ 3 - 3
src/porting_android.h

@@ -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