mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-01-19 04:13:24 +00:00
Add content URI support to LocalFileLoader, remove ContentUriFileLoader
This commit is contained in:
parent
ad72dc8748
commit
1aed8ce7b1
@ -25,6 +25,10 @@
|
||||
#include "Common/File/DirListing.h"
|
||||
#include "Core/FileLoaders/LocalFileLoader.h"
|
||||
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
#include "android/jni/app-android.h"
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "Common/CommonWindows.h"
|
||||
#else
|
||||
@ -32,11 +36,6 @@
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
LocalFileLoader::LocalFileLoader(int fd, const Path &filename) : fd_(fd), filename_(filename), isOpenedByFd_(fd != -1) {
|
||||
if (fd != -1) {
|
||||
DetectSizeFd();
|
||||
}
|
||||
}
|
||||
|
||||
void LocalFileLoader::DetectSizeFd() {
|
||||
#if PPSSPP_PLATFORM(ANDROID) || (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS < 64)
|
||||
@ -52,11 +51,27 @@ void LocalFileLoader::DetectSizeFd() {
|
||||
#endif
|
||||
|
||||
LocalFileLoader::LocalFileLoader(const Path &filename)
|
||||
: filesize_(0), filename_(filename), isOpenedByFd_(false) {
|
||||
: filesize_(0), filename_(filename) {
|
||||
if (filename.empty()) {
|
||||
ERROR_LOG(FILESYS, "LocalFileLoader can't load empty filenames");
|
||||
return;
|
||||
}
|
||||
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
if (filename.Type() == PathType::CONTENT_URI) {
|
||||
int fd = Android_OpenContentUriFd(filename.ToString(), Android_OpenContentUriMode::READ);
|
||||
INFO_LOG(SYSTEM, "Fd %d for content URI: '%s'", fd, filename.c_str());
|
||||
if (fd == -1) {
|
||||
ERROR_LOG(FILESYS, "LoadFileLoader failed to open content URI: '%s'", filename.c_str());
|
||||
return;
|
||||
}
|
||||
fd_ = fd;
|
||||
isOpenedByFd_ = true;
|
||||
DetectSizeFd();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
fd_ = open(filename.c_str(), O_RDONLY | O_CLOEXEC);
|
||||
@ -106,14 +121,18 @@ bool LocalFileLoader::Exists() {
|
||||
// If we couldn't open it for reading, we say it does not exist.
|
||||
#ifndef _WIN32
|
||||
if (isOpenedByFd_) {
|
||||
return true;
|
||||
return fd_ != -1;
|
||||
}
|
||||
if (fd_ != -1 || IsDirectory()) {
|
||||
#else
|
||||
if (handle_ != INVALID_HANDLE_VALUE || IsDirectory()) {
|
||||
#endif
|
||||
File::FileInfo info;
|
||||
return File::GetFileInfo(filename_, &info);
|
||||
if (File::GetFileInfo(filename_, &info)) {
|
||||
return info.exists;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -121,7 +140,7 @@ bool LocalFileLoader::Exists() {
|
||||
bool LocalFileLoader::IsDirectory() {
|
||||
File::FileInfo info;
|
||||
if (File::GetFileInfo(filename_, &info)) {
|
||||
return info.isDirectory;
|
||||
return info.exists && info.isDirectory;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -134,6 +153,11 @@ size_t LocalFileLoader::ReadAt(s64 absolutePos, size_t bytes, size_t count, void
|
||||
if (bytes == 0)
|
||||
return 0;
|
||||
|
||||
if (filesize_ == 0) {
|
||||
ERROR_LOG(FILESYS, "ReadAt from 0-sized file: %s", filename_.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if PPSSPP_PLATFORM(SWITCH)
|
||||
// Toolchain has no fancy IO API. We must lock.
|
||||
std::lock_guard<std::mutex> guard(readLock_);
|
||||
|
@ -30,7 +30,6 @@ typedef void *HANDLE;
|
||||
class LocalFileLoader : public FileLoader {
|
||||
public:
|
||||
LocalFileLoader(const Path &filename);
|
||||
LocalFileLoader(const int fd, const Path &filename);
|
||||
virtual ~LocalFileLoader();
|
||||
|
||||
virtual bool Exists() override;
|
||||
@ -44,12 +43,12 @@ public:
|
||||
private:
|
||||
#ifndef _WIN32
|
||||
void DetectSizeFd();
|
||||
int fd_;
|
||||
int fd_ = -1;
|
||||
#else
|
||||
HANDLE handle_;
|
||||
HANDLE handle_ = 0;
|
||||
#endif
|
||||
u64 filesize_;
|
||||
u64 filesize_ = 0;
|
||||
Path filename_;
|
||||
std::mutex readLock_;
|
||||
bool isOpenedByFd_;
|
||||
bool isOpenedByFd_ = false;
|
||||
};
|
||||
|
@ -337,6 +337,9 @@ std::vector<File::FileInfo> Android_ListContentUri(const std::string &path) {
|
||||
return std::vector<File::FileInfo>();
|
||||
}
|
||||
auto env = getEnv();
|
||||
|
||||
double start = time_now_d();
|
||||
|
||||
jstring param = env->NewStringUTF(path.c_str());
|
||||
jobject retval = env->CallObjectMethod(nativeActivity, listContentUriDir, param);
|
||||
|
||||
@ -357,6 +360,9 @@ std::vector<File::FileInfo> Android_ListContentUri(const std::string &path) {
|
||||
env->DeleteLocalRef(str);
|
||||
}
|
||||
env->DeleteLocalRef(fileList);
|
||||
|
||||
double elapsed = time_now_d() - start;
|
||||
INFO_LOG(FILESYS, "Listing directory on content URI took %0.3f s");
|
||||
return items;
|
||||
}
|
||||
|
||||
@ -380,33 +386,6 @@ int64_t Android_GetFreeSpaceByFilePath(const std::string &filePath) {
|
||||
return env->CallLongMethod(nativeActivity, filePathGetFreeStorageSpace, param);
|
||||
}
|
||||
|
||||
|
||||
class ContentURIFileLoader : public ProxiedFileLoader {
|
||||
public:
|
||||
ContentURIFileLoader(const Path &filename)
|
||||
: ProxiedFileLoader(nullptr) { // we overwrite the nullptr below
|
||||
int fd = Android_OpenContentUriFd(filename.ToString(), Android_OpenContentUriMode::READ);
|
||||
INFO_LOG(SYSTEM, "Fd %d for content URI: '%s'", fd, filename.c_str());
|
||||
backend_ = new LocalFileLoader(fd, filename);
|
||||
}
|
||||
|
||||
bool ExistsFast() override {
|
||||
if (!nativeActivity) {
|
||||
// Assume it does if we don't have a NativeActivity right now.
|
||||
return true;
|
||||
}
|
||||
return backend_->ExistsFast();
|
||||
}
|
||||
};
|
||||
|
||||
class AndroidContentLoaderFactory : public FileLoaderFactory {
|
||||
public:
|
||||
AndroidContentLoaderFactory() {}
|
||||
FileLoader *ConstructFileLoader(const Path &filename) override {
|
||||
return new ContentURIFileLoader(filename);
|
||||
}
|
||||
};
|
||||
|
||||
JNIEnv* getEnv() {
|
||||
JNIEnv *env;
|
||||
int status = gJvm->GetEnv((void**)&env, JNI_VERSION_1_6);
|
||||
@ -851,11 +830,6 @@ extern "C" void Java_org_ppsspp_ppsspp_NativeApp_init
|
||||
|
||||
NativeInit((int)args.size(), &args[0], user_data_path.c_str(), externalStorageDir.c_str(), cacheDir.c_str());
|
||||
|
||||
std::unique_ptr<FileLoaderFactory> factory(new AndroidContentLoaderFactory());
|
||||
|
||||
// Register a content URI file loader.
|
||||
RegisterFileLoaderFactory("content://", std::move(factory));
|
||||
|
||||
// No need to use EARLY_LOG anymore.
|
||||
|
||||
retry:
|
||||
|
Loading…
x
Reference in New Issue
Block a user