diff --git a/src/Context.cpp b/src/Context.cpp index 5a6314a0c0..d8918aad2b 100644 --- a/src/Context.cpp +++ b/src/Context.cpp @@ -272,3 +272,10 @@ CJNIResources CJNIContext::getResources() return call_method(m_context, "getResources", "()Landroid/content/res/Resources;"); } + +void CJNIContext::grantUriPermission(const std::string& package, const CJNIURI& uri, int flags) +{ + call_method(m_context, + "grantUriPermission", "(Ljava/lang/String;Landroid/net/Uri;I)V", + jcast(package), uri.get_raw(), flags); +} diff --git a/src/Context.h b/src/Context.h index 398be521e2..f1db83f38f 100644 --- a/src/Context.h +++ b/src/Context.h @@ -34,6 +34,7 @@ class CJNIContentResolver; class CJNIWindow; class CJNIResourcesTheme; class CJNIResources; +class CJNIURI; class CJNIContext { @@ -70,6 +71,7 @@ class CJNIContext static CJNIWindow getWindow(); static CJNIResourcesTheme getTheme(); static CJNIResources getResources(); + static void grantUriPermission(const std::string& package, const CJNIURI& uri, int flags); protected: CJNIContext(const ANativeActivity *nativeActivity); diff --git a/src/File.cpp b/src/File.cpp index 4482cbfd14..2e4a04ab0c 100644 --- a/src/File.cpp +++ b/src/File.cpp @@ -23,6 +23,17 @@ using namespace jni; +CJNIFile::CJNIFile(const std::string& pathname) : CJNIBase("java/io/File") +{ + m_object = new_object(GetClassName(), "", "(Ljava/lang/String;)V", jcast(pathname)); + m_object.setGlobal(); +} + +bool CJNIFile::exists() +{ + return call_method(m_object, "exists", "()Z"); +} + std::string CJNIFile::getAbsolutePath() { return jcast(call_method(m_object, diff --git a/src/File.h b/src/File.h index dc1f2fa36f..b291e55d75 100644 --- a/src/File.h +++ b/src/File.h @@ -26,8 +26,10 @@ class CJNIFile : public CJNIBase public: CJNIFile(); CJNIFile(const jni::jhobject &file) : CJNIBase(file){}; + CJNIFile(const std::string& pathname); ~CJNIFile(){}; + bool exists(); std::string getAbsolutePath(); int64_t getUsableSpace(); }; diff --git a/src/FileProvider.cpp b/src/FileProvider.cpp new file mode 100644 index 0000000000..a483f3c14e --- /dev/null +++ b/src/FileProvider.cpp @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2024 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "FileProvider.h" + +#include "jutils-details.hpp" + +using namespace jni; + +const std::string CJNIFileProvider::m_classname = "androidx/core/content/FileProvider"; + +const CJNIURI CJNIFileProvider::getUriForFile(const CJNIContext& context, const std::string& authority, const CJNIFile& file) +{ + const jhclass clazz = CJNIContext::getClassLoader().loadClass(m_classname); + + return call_static_method(clazz, + "getUriForFile", "(Landroid/content/Context;Ljava/lang/String;Ljava/io/File;)Landroid/net/Uri;", + context.get_raw(), jcast(authority), file.get_raw()); +}; diff --git a/src/FileProvider.h b/src/FileProvider.h new file mode 100644 index 0000000000..6ff584e850 --- /dev/null +++ b/src/FileProvider.h @@ -0,0 +1,22 @@ +#pragma once +/* + * Copyright (C) 2024 Team Kodi + * This file is part of Kodi - https://kodi.tv + * + * SPDX-License-Identifier: GPL-2.0-or-later + * See LICENSES/README.md for more information. + */ + +#include "JNIBase.h" +#include "Context.h" +#include "File.h" +#include "URI.h" + +class CJNIFileProvider : public CJNIBase +{ +public: + static const CJNIURI getUriForFile(const CJNIContext& context, const std::string& authority, const CJNIFile& file); + +private: + static const std::string m_classname; +}; diff --git a/src/Intent.cpp b/src/Intent.cpp index 8ed1fde381..7f437f0d4b 100644 --- a/src/Intent.cpp +++ b/src/Intent.cpp @@ -43,6 +43,8 @@ std::string CJNIIntent::ACTION_SCREEN_OFF; std::string CJNIIntent::ACTION_SEARCH; std::string CJNIIntent::ACTION_VIEW; std::string CJNIIntent::EXTRA_KEY_EVENT; +int CJNIIntent::FLAG_GRANT_READ_URI_PERMISSION; +int CJNIIntent::FLAG_GRANT_WRITE_URI_PERMISSION; static std::string s_className = "android/content/Intent"; @@ -67,6 +69,8 @@ void CJNIIntent::PopulateStaticFields() ACTION_SEARCH = jcast(get_static_field(clazz,"ACTION_SEARCH")); ACTION_VIEW = jcast(get_static_field(clazz,"ACTION_VIEW")); EXTRA_KEY_EVENT = jcast(get_static_field(clazz,"EXTRA_KEY_EVENT")); + FLAG_GRANT_READ_URI_PERMISSION = (get_static_field(clazz, "FLAG_GRANT_READ_URI_PERMISSION")); + FLAG_GRANT_WRITE_URI_PERMISSION = (get_static_field(clazz, "FLAG_GRANT_WRITE_URI_PERMISSION")); } CJNIIntent::CJNIIntent(const std::string &action) diff --git a/src/Intent.h b/src/Intent.h index f7904b5f13..e8c8450bc2 100644 --- a/src/Intent.h +++ b/src/Intent.h @@ -83,4 +83,6 @@ class CJNIIntent : public CJNIBase static std::string ACTION_SEARCH; static std::string ACTION_VIEW; static std::string EXTRA_KEY_EVENT; + static int FLAG_GRANT_READ_URI_PERMISSION; + static int FLAG_GRANT_WRITE_URI_PERMISSION; };