diff --git a/Common/File/AndroidStorage.cpp b/Common/File/AndroidStorage.cpp index 552be7686d..4eb11b20e7 100644 --- a/Common/File/AndroidStorage.cpp +++ b/Common/File/AndroidStorage.cpp @@ -36,11 +36,11 @@ void Android_RegisterStorageCallbacks(JNIEnv * env, jobject obj) { _dbg_assert_(contentUriCreateDirectory); contentUriCreateFile = env->GetMethodID(env->GetObjectClass(obj), "contentUriCreateFile", "(Ljava/lang/String;Ljava/lang/String;)Z"); _dbg_assert_(contentUriCreateFile); - contentUriCopyFile = env->GetMethodID(env->GetObjectClass(obj), "contentUriCopyFile", "(Ljava/lang/String;Ljava/lang/String;)Z"); + contentUriCopyFile = env->GetMethodID(env->GetObjectClass(obj), "contentUriCopyFile", "(Ljava/lang/String;Ljava/lang/String;)I"); _dbg_assert_(contentUriCopyFile); - contentUriRemoveFile = env->GetMethodID(env->GetObjectClass(obj), "contentUriRemoveFile", "(Ljava/lang/String;)Z"); + contentUriRemoveFile = env->GetMethodID(env->GetObjectClass(obj), "contentUriRemoveFile", "(Ljava/lang/String;)I"); _dbg_assert_(contentUriRemoveFile); - contentUriMoveFile = env->GetMethodID(env->GetObjectClass(obj), "contentUriMoveFile", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)Z"); + contentUriMoveFile = env->GetMethodID(env->GetObjectClass(obj), "contentUriMoveFile", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I"); _dbg_assert_(contentUriMoveFile); contentUriRenameFileTo = env->GetMethodID(env->GetObjectClass(obj), "contentUriRenameFileTo", "(Ljava/lang/String;Ljava/lang/String;)I"); _dbg_assert_(contentUriRenameFileTo); @@ -104,34 +104,34 @@ bool Android_CreateFile(const std::string &parentTreeUri, const std::string &fil return env->CallBooleanMethod(g_nativeActivity, contentUriCreateFile, paramRoot, paramFileName); } -bool Android_CopyFile(const std::string &fileUri, const std::string &destParentUri) { +StorageError Android_CopyFile(const std::string &fileUri, const std::string &destParentUri) { if (!g_nativeActivity) { - return false; + return StorageError::UNKNOWN; } auto env = getEnv(); jstring paramFileName = env->NewStringUTF(fileUri.c_str()); jstring paramDestParentUri = env->NewStringUTF(destParentUri.c_str()); - return env->CallBooleanMethod(g_nativeActivity, contentUriCopyFile, paramFileName, paramDestParentUri); + return StorageErrorFromInt(env->CallIntMethod(g_nativeActivity, contentUriCopyFile, paramFileName, paramDestParentUri)); } -bool Android_MoveFile(const std::string &fileUri, const std::string &srcParentUri, const std::string &destParentUri) { +StorageError Android_MoveFile(const std::string &fileUri, const std::string &srcParentUri, const std::string &destParentUri) { if (!g_nativeActivity) { - return false; + return StorageError::UNKNOWN; } auto env = getEnv(); jstring paramFileName = env->NewStringUTF(fileUri.c_str()); jstring paramSrcParentUri = env->NewStringUTF(srcParentUri.c_str()); jstring paramDestParentUri = env->NewStringUTF(destParentUri.c_str()); - return env->CallBooleanMethod(g_nativeActivity, contentUriMoveFile, paramFileName, paramSrcParentUri, paramDestParentUri); + return StorageErrorFromInt(env->CallIntMethod(g_nativeActivity, contentUriMoveFile, paramFileName, paramSrcParentUri, paramDestParentUri)); } -bool Android_RemoveFile(const std::string &fileUri) { +StorageError Android_RemoveFile(const std::string &fileUri) { if (!g_nativeActivity) { - return false; + return StorageError::UNKNOWN; } auto env = getEnv(); jstring paramFileName = env->NewStringUTF(fileUri.c_str()); - return env->CallBooleanMethod(g_nativeActivity, contentUriRemoveFile, paramFileName); + return StorageErrorFromInt(env->CallIntMethod(g_nativeActivity, contentUriRemoveFile, paramFileName)); } StorageError Android_RenameFileTo(const std::string &fileUri, const std::string &newName) { diff --git a/Common/File/AndroidStorage.h b/Common/File/AndroidStorage.h index 6510f16985..be766fb97e 100644 --- a/Common/File/AndroidStorage.h +++ b/Common/File/AndroidStorage.h @@ -42,9 +42,9 @@ bool Android_IsContentUri(const std::string &uri); int Android_OpenContentUriFd(const std::string &uri, const Android_OpenContentUriMode mode); bool Android_CreateDirectory(const std::string &parentTreeUri, const std::string &dirName); bool Android_CreateFile(const std::string &parentTreeUri, const std::string &fileName); -bool Android_MoveFile(const std::string &fileUri, const std::string &srcParentUri, const std::string &destParentUri); -bool Android_CopyFile(const std::string &fileUri, const std::string &destParentUri); -bool Android_RemoveFile(const std::string &fileUri); +StorageError Android_MoveFile(const std::string &fileUri, const std::string &srcParentUri, const std::string &destParentUri); +StorageError Android_CopyFile(const std::string &fileUri, const std::string &destParentUri); +StorageError Android_RemoveFile(const std::string &fileUri); StorageError Android_RenameFileTo(const std::string &fileUri, const std::string &newName); bool Android_GetFileInfo(const std::string &fileUri, File::FileInfo *info); bool Android_FileExists(const std::string &fileUri); @@ -67,9 +67,9 @@ inline bool Android_IsContentUri(const std::string &uri) { return false; } inline int Android_OpenContentUriFd(const std::string &uri, const Android_OpenContentUriMode mode) { return -1; } inline bool Android_CreateDirectory(const std::string &parentTreeUri, const std::string &dirName) { return false; } inline bool Android_CreateFile(const std::string &parentTreeUri, const std::string &fileName) { return false; } -inline bool Android_MoveFile(const std::string &fileUri, const std::string &srcParentUri, const std::string &destParentUri) { return false; } -inline bool Android_CopyFile(const std::string &fileUri, const std::string &destParentUri) { return false; } -inline bool Android_RemoveFile(const std::string &fileUri) { return false; } +inline StorageError Android_MoveFile(const std::string &fileUri, const std::string &srcParentUri, const std::string &destParentUri) { return StorageError::UNKNOWN; } +inline StorageError Android_CopyFile(const std::string &fileUri, const std::string &destParentUri) { return StorageError::UNKNOWN; } +inline StorageError Android_RemoveFile(const std::string &fileUri) { return StorageError::UNKNOWN; } inline StorageError Android_RenameFileTo(const std::string &fileUri, const std::string &newName) { return StorageError::UNKNOWN; } inline bool Android_GetFileInfo(const std::string &fileUri, File::FileInfo *info) { return false; } inline bool Android_FileExists(const std::string &fileUri) { return false; } diff --git a/Common/File/FileUtil.cpp b/Common/File/FileUtil.cpp index 7c58f83f9b..9684b3b26c 100644 --- a/Common/File/FileUtil.cpp +++ b/Common/File/FileUtil.cpp @@ -396,7 +396,7 @@ bool Delete(const Path &filename) { case PathType::NATIVE: break; // OK case PathType::CONTENT_URI: - return Android_RemoveFile(filename.ToString()); + return Android_RemoveFile(filename.ToString()) == StorageError::SUCCESS; default: return false; } @@ -439,6 +439,12 @@ bool CreateDir(const Path &path) { break; // OK case PathType::CONTENT_URI: { + // NOTE: The Android storage API will simply create a renamed directory (append a number) if it already exists. + // We want to avoid that, so let's just return true if the directory already is there. + if (File::Exists(path)) { + return true; + } + // Convert it to a "CreateDirIn" call, if possible, since that's // what we can do with the storage API. AndroidContentURI uri(path.ToString()); @@ -532,7 +538,7 @@ bool DeleteDir(const Path &path) { case PathType::NATIVE: break; // OK case PathType::CONTENT_URI: - return Android_RemoveFile(path.ToString()); + return Android_RemoveFile(path.ToString()) == StorageError::SUCCESS; default: return false; } @@ -609,7 +615,7 @@ bool Copy(const Path &srcFilename, const Path &destFilename) { if (destFilename.Type() == PathType::CONTENT_URI && destFilename.CanNavigateUp()) { Path destParent = destFilename.NavigateUp(); // Use native file copy. - if (Android_CopyFile(srcFilename.ToString(), destParent.ToString())) { + if (Android_CopyFile(srcFilename.ToString(), destParent.ToString()) == StorageError::SUCCESS) { return true; } // Else fall through, and try using file I/O. @@ -689,6 +695,7 @@ bool Copy(const Path &srcFilename, const Path &destFilename) { #endif } +// Will overwrite the target. bool Move(const Path &srcFilename, const Path &destFilename) { // Try a shortcut in Android Storage scenarios. if (srcFilename.Type() == PathType::CONTENT_URI && destFilename.Type() == PathType::CONTENT_URI && srcFilename.CanNavigateUp() && destFilename.CanNavigateUp()) { @@ -696,7 +703,7 @@ bool Move(const Path &srcFilename, const Path &destFilename) { if (srcFilename.GetFilename() == destFilename.GetFilename()) { Path srcParent = srcFilename.NavigateUp(); Path dstParent = destFilename.NavigateUp(); - if (Android_MoveFile(srcFilename.ToString(), srcParent.ToString(), dstParent.ToString())) { + if (Android_MoveFile(srcFilename.ToString(), srcParent.ToString(), dstParent.ToString()) == StorageError::SUCCESS) { return true; } // If failed, fall through and try other ways. diff --git a/android/src/org/ppsspp/ppsspp/PpssppActivity.java b/android/src/org/ppsspp/ppsspp/PpssppActivity.java index dedd1d549a..dc1869d7b2 100644 --- a/android/src/org/ppsspp/ppsspp/PpssppActivity.java +++ b/android/src/org/ppsspp/ppsspp/PpssppActivity.java @@ -248,45 +248,45 @@ public class PpssppActivity extends NativeActivity { } } - public boolean contentUriRemoveFile(String fileName) { + public int contentUriRemoveFile(String fileName) { try { Uri uri = Uri.parse(fileName); DocumentFile documentFile = DocumentFile.fromSingleUri(this, uri); if (documentFile != null) { - return documentFile.delete(); + return documentFile.delete() ? STORAGE_ERROR_SUCCESS : STORAGE_ERROR_UNKNOWN; } else { - return false; + return STORAGE_ERROR_UNKNOWN; } } catch (Exception e) { Log.e(TAG, "contentUriRemoveFile exception: " + e.toString()); - return false; + return STORAGE_ERROR_UNKNOWN; } } // NOTE: The destination is the parent directory! This means that contentUriCopyFile // cannot rename things as part of the operation. - public boolean contentUriCopyFile(String srcFileUri, String dstParentDirUri) { + public int contentUriCopyFile(String srcFileUri, String dstParentDirUri) { try { Uri srcUri = Uri.parse(srcFileUri); Uri dstParentUri = Uri.parse(dstParentDirUri); - return DocumentsContract.copyDocument(getContentResolver(), srcUri, dstParentUri) != null; + return DocumentsContract.copyDocument(getContentResolver(), srcUri, dstParentUri) != null ? STORAGE_ERROR_SUCCESS : STORAGE_ERROR_UNKNOWN; } catch (Exception e) { Log.e(TAG, "contentUriCopyFile exception: " + e.toString()); - return false; + return STORAGE_ERROR_UNKNOWN; } } // NOTE: The destination is the parent directory! This means that contentUriCopyFile // cannot rename things as part of the operation. - public boolean contentUriMoveFile(String srcFileUri, String srcParentDirUri, String dstParentDirUri) { + public int contentUriMoveFile(String srcFileUri, String srcParentDirUri, String dstParentDirUri) { try { Uri srcUri = Uri.parse(srcFileUri); Uri srcParentUri = Uri.parse(srcParentDirUri); Uri dstParentUri = Uri.parse(dstParentDirUri); - return DocumentsContract.moveDocument(getContentResolver(), srcUri, srcParentUri, dstParentUri) != null; + return DocumentsContract.moveDocument(getContentResolver(), srcUri, srcParentUri, dstParentUri) != null ? STORAGE_ERROR_SUCCESS : STORAGE_ERROR_UNKNOWN; } catch (Exception e) { Log.e(TAG, "contentUriMoveFile exception: " + e.toString()); - return false; + return STORAGE_ERROR_UNKNOWN; } }