From 58771fc41c411769d3ab7248c7fab00e8dbbecef Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 1 Mar 2014 17:46:59 +0100 Subject: Android: obtain music directory from Environment.getExternalStoragePublicDirectory() --- Makefile.am | 7 ++- src/Main.cxx | 4 ++ src/android/Environment.cxx | 117 +++++++++++++++++++++++++++++++++++++++++++ src/android/Environment.hxx | 43 ++++++++++++++++ src/fs/StandardDirectory.cxx | 15 +++++- 5 files changed, 184 insertions(+), 2 deletions(-) create mode 100644 src/android/Environment.cxx create mode 100644 src/android/Environment.hxx diff --git a/Makefile.am b/Makefile.am index c4235e60b..8f5ff1be2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -252,12 +252,17 @@ libjava_a_SOURCES = \ src/java/File.cxx src/java/File.hxx \ src/java/String.cxx src/java/String.hxx +noinst_LIBRARIES += libandroid.a +libandroid_a_SOURCES = \ + src/android/Environment.cxx src/android/Environment.hxx +libandroid_a_CPPFLAGS = $(AM_CPPFLAGS) -Iandroid/build/include + noinst_LIBRARIES += libmain.a libmain_a_SOURCES = \ src/Main.cxx src/Main.hxx libmain_a_CPPFLAGS = $(AM_CPPFLAGS) -Iandroid/build/include -src_mpd_LDADD += libjava.a +src_mpd_LDADD += libandroid.a libjava.a all-local: android/build/bin/Main-debug.apk clean-local: diff --git a/src/Main.cxx b/src/Main.cxx index 6a04e5071..c8290e3ff 100644 --- a/src/Main.cxx +++ b/src/Main.cxx @@ -92,6 +92,7 @@ #ifdef ANDROID #include "java/Global.hxx" #include "java/File.hxx" +#include "android/Environment.hxx" #include "org_musicpd_Bridge.h" #endif @@ -679,8 +680,11 @@ Java_org_musicpd_Bridge_run(JNIEnv *env, jclass) { Java::Init(env); Java::File::Initialise(env); + Environment::Initialise(env); mpd_main(0, nullptr); + + Environment::Deinitialise(env); } #endif diff --git a/src/android/Environment.cxx b/src/android/Environment.cxx new file mode 100644 index 000000000..40f4cfd41 --- /dev/null +++ b/src/android/Environment.cxx @@ -0,0 +1,117 @@ +/* +Copyright_License { + + XCSoar Glide Computer - http://www.xcsoar.org/ + Copyright (C) 2000-2013 The XCSoar Project + A detailed list of copyright holders can be found in the file "AUTHORS". + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +} +*/ + +#include "Environment.hxx" +#include "java/Class.hxx" +#include "java/String.hxx" +#include "java/File.hxx" +#include "util/StringUtil.hxx" + +namespace Environment { + static Java::TrivialClass cls; + static jmethodID getExternalStorageDirectory_method; + static jmethodID getExternalStoragePublicDirectory_method; + + static jstring getExternalStorageDirectory(JNIEnv *env); +}; + +void +Environment::Initialise(JNIEnv *env) +{ + cls.Find(env, "android/os/Environment"); + + getExternalStorageDirectory_method = + env->GetStaticMethodID(cls, "getExternalStorageDirectory", + "()Ljava/io/File;"); + + getExternalStoragePublicDirectory_method = + env->GetStaticMethodID(cls, "getExternalStoragePublicDirectory", + "(Ljava/lang/String;)Ljava/io/File;"); +} + +void +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) +{ + JNIEnv *env = Java::GetEnv(); + + jstring value = getExternalStorageDirectory(env); + if (value == nullptr) + return nullptr; + + Java::String value2(env, value); + value2.CopyTo(env, buffer, max_size); + return buffer; +} + +static jstring +getExternalStoragePublicDirectory(JNIEnv *env, const char *type) +{ + if (Environment::getExternalStoragePublicDirectory_method == nullptr) + /* needs API level 8 */ + return nullptr; + + Java::String type2(env, type); + jobject file = env->CallStaticObjectMethod(Environment::cls, + Environment::getExternalStoragePublicDirectory_method, + type2.Get()); + return ToAbsolutePathChecked(env, file); +} + +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; +} diff --git a/src/android/Environment.hxx b/src/android/Environment.hxx new file mode 100644 index 000000000..d2b02d1e9 --- /dev/null +++ b/src/android/Environment.hxx @@ -0,0 +1,43 @@ +/* +Copyright_License { + + XCSoar Glide Computer - http://www.xcsoar.org/ + Copyright (C) 2000-2013 The XCSoar Project + A detailed list of copyright holders can be found in the file "AUTHORS". + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +} +*/ + +#ifndef MPD_ANDROID_ENVIRONMENT_HXX +#define MPD_ANDROID_ENVIRONMENT_HXX + +#include +#include + +namespace Environment { + void Initialise(JNIEnv *env); + void Deinitialise(JNIEnv *env); + + /** + * Determine the mount point of the external SD card. + */ + char *getExternalStorageDirectory(char *buffer, size_t max_size); + + char *getExternalStoragePublicDirectory(char *buffer, size_t max_size, + const char *type); +}; + +#endif diff --git a/src/fs/StandardDirectory.cxx b/src/fs/StandardDirectory.cxx index 4f0958995..fce54a677 100644 --- a/src/fs/StandardDirectory.cxx +++ b/src/fs/StandardDirectory.cxx @@ -20,7 +20,7 @@ #include "config.h" // Use X Desktop guidelines where applicable -#if !defined(__APPLE__) && !defined(WIN32) +#if !defined(__APPLE__) && !defined(WIN32) && !defined(ANDROID) #define USE_XDG #endif @@ -47,6 +47,11 @@ #include #endif +#ifdef ANDROID +#include "java/Global.hxx" +#include "android/Environment.hxx" +#endif + #ifndef WIN32 class PasswdEntry { @@ -240,6 +245,14 @@ AllocatedPath GetUserMusicDir() return GetStandardDir(CSIDL_MYMUSIC); #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); #else return AllocatedPath::Null(); #endif -- cgit v1.2.3