diff --git a/src/android/Environment.cxx b/src/android/Environment.cxx index 7cebb57ca..9813b0b79 100644 --- a/src/android/Environment.cxx +++ b/src/android/Environment.cxx @@ -17,18 +17,18 @@ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ +#include "config.h" #include "Environment.hxx" #include "java/Class.hxx" #include "java/String.hxx" #include "java/File.hxx" #include "util/StringUtil.hxx" +#include "fs/AllocatedPath.hxx" namespace Environment { static Java::TrivialClass cls; static jmethodID getExternalStorageDirectory_method; static jmethodID getExternalStoragePublicDirectory_method; - - static jstring getExternalStorageDirectory(JNIEnv *env); }; void @@ -51,63 +51,35 @@ Environment::Deinitialise(JNIEnv *env) cls.Clear(env); } -static jstring -ToAbsolutePathChecked(JNIEnv *env, jobject file) -{ - if (file == nullptr) - return nullptr; - - jstring path = Java::File::getAbsolutePath(env, file); - env->DeleteLocalRef(file); - return path; -} - -static jstring -Environment::getExternalStorageDirectory(JNIEnv *env) -{ - jobject file = env->CallStaticObjectMethod(cls, - getExternalStorageDirectory_method); - return ToAbsolutePathChecked(env, file); -} - -char * -Environment::getExternalStorageDirectory(char *buffer, size_t max_size) +AllocatedPath +Environment::getExternalStorageDirectory() { JNIEnv *env = Java::GetEnv(); - jstring value = getExternalStorageDirectory(env); - if (value == nullptr) - return nullptr; + jobject file = + env->CallStaticObjectMethod(cls, + getExternalStorageDirectory_method); + if (file == nullptr) + return AllocatedPath::Null(); - Java::String value2(env, value); - value2.CopyTo(env, buffer, max_size); - return buffer; + return Java::File::ToAbsolutePath(env, file); } -static jstring -getExternalStoragePublicDirectory(JNIEnv *env, const char *type) +AllocatedPath +Environment::getExternalStoragePublicDirectory(const char *type) { - if (Environment::getExternalStoragePublicDirectory_method == nullptr) + if (getExternalStoragePublicDirectory_method == nullptr) /* needs API level 8 */ - return nullptr; + return AllocatedPath::Null(); + + JNIEnv *env = Java::GetEnv(); Java::String type2(env, type); jobject file = env->CallStaticObjectMethod(Environment::cls, Environment::getExternalStoragePublicDirectory_method, type2.Get()); - return ToAbsolutePathChecked(env, file); -} + if (file == nullptr) + return AllocatedPath::Null(); -char * -Environment::getExternalStoragePublicDirectory(char *buffer, size_t max_size, - const char *type) -{ - JNIEnv *env = Java::GetEnv(); - jstring path = ::getExternalStoragePublicDirectory(env, type); - if (path == nullptr) - return nullptr; - - Java::String path2(env, path); - path2.CopyTo(env, buffer, max_size); - return buffer; + return Java::File::ToAbsolutePath(env, file); } diff --git a/src/android/Environment.hxx b/src/android/Environment.hxx index 054ffc6f2..5a54ea361 100644 --- a/src/android/Environment.hxx +++ b/src/android/Environment.hxx @@ -20,8 +20,11 @@ #ifndef MPD_ANDROID_ENVIRONMENT_HXX #define MPD_ANDROID_ENVIRONMENT_HXX +#include "Compiler.h" + #include -#include + +class AllocatedPath; namespace Environment { void Initialise(JNIEnv *env); @@ -30,10 +33,11 @@ namespace Environment { /** * Determine the mount point of the external SD card. */ - char *getExternalStorageDirectory(char *buffer, size_t max_size); + gcc_pure + AllocatedPath getExternalStorageDirectory(); - char *getExternalStoragePublicDirectory(char *buffer, size_t max_size, - const char *type); + gcc_pure + AllocatedPath getExternalStoragePublicDirectory(const char *type); }; #endif diff --git a/src/fs/StandardDirectory.cxx b/src/fs/StandardDirectory.cxx index fce54a677..20d66bb10 100644 --- a/src/fs/StandardDirectory.cxx +++ b/src/fs/StandardDirectory.cxx @@ -246,13 +246,7 @@ AllocatedPath GetUserMusicDir() #elif defined(USE_XDG) return GetUserDir("XDG_MUSIC_DIR"); #elif defined(ANDROID) - char buffer[1024]; - if (Environment::getExternalStoragePublicDirectory(buffer, - sizeof(buffer), - "Music") == nullptr) - return AllocatedPath::Null(); - - return AllocatedPath::FromUTF8(buffer); + return Environment::getExternalStoragePublicDirectory("Music"); #else return AllocatedPath::Null(); #endif diff --git a/src/java/File.cxx b/src/java/File.cxx index 03e3defdf..8e9599dfc 100644 --- a/src/java/File.cxx +++ b/src/java/File.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2012 Max Kellermann + * Copyright (C) 2010-2014 Max Kellermann * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -27,8 +27,13 @@ * OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include "config.h" #include "File.hxx" #include "Class.hxx" +#include "String.hxx" +#include "Object.hxx" +#include "fs/AllocatedPath.hxx" +#include "fs/Limits.hxx" jmethodID Java::File::getAbsolutePath_method; @@ -40,3 +45,23 @@ Java::File::Initialise(JNIEnv *env) getAbsolutePath_method = env->GetMethodID(cls, "getAbsolutePath", "()Ljava/lang/String;"); } + +AllocatedPath +Java::File::ToAbsolutePath(JNIEnv *env, jobject _file) +{ + assert(env != nullptr); + assert(_file != nullptr); + + LocalObject file(env, _file); + + const jstring path = getAbsolutePath(env, file); + if (path == nullptr) { + env->ExceptionClear(); + return AllocatedPath::Null(); + } + + Java::String path2(env, path); + char buffer[MPD_PATH_MAX]; + path2.CopyTo(env, buffer, sizeof(buffer)); + return AllocatedPath::FromUTF8(buffer); +} diff --git a/src/java/File.hxx b/src/java/File.hxx index 57af6199c..3636fc7c6 100644 --- a/src/java/File.hxx +++ b/src/java/File.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010-2012 Max Kellermann + * Copyright (C) 2010-2014 Max Kellermann * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -34,6 +34,8 @@ #include +class AllocatedPath; + namespace Java { /** * Wrapper for a java.io.File object. @@ -42,12 +44,22 @@ namespace Java { static jmethodID getAbsolutePath_method; public: + gcc_nonnull_all static void Initialise(JNIEnv *env); + gcc_nonnull_all static jstring getAbsolutePath(JNIEnv *env, jobject file) { return (jstring)env->CallObjectMethod(file, getAbsolutePath_method); } + + /** + * Invoke File.getAbsolutePath() and release the + * specified File reference. + */ + gcc_pure gcc_nonnull_all + static AllocatedPath ToAbsolutePath(JNIEnv *env, + jobject file); }; }