Path: blob/master/platform/android/dir_access_jandroid.cpp
10277 views
/**************************************************************************/1/* dir_access_jandroid.cpp */2/**************************************************************************/3/* This file is part of: */4/* GODOT ENGINE */5/* https://godotengine.org */6/**************************************************************************/7/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */8/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */9/* */10/* Permission is hereby granted, free of charge, to any person obtaining */11/* a copy of this software and associated documentation files (the */12/* "Software"), to deal in the Software without restriction, including */13/* without limitation the rights to use, copy, modify, merge, publish, */14/* distribute, sublicense, and/or sell copies of the Software, and to */15/* permit persons to whom the Software is furnished to do so, subject to */16/* the following conditions: */17/* */18/* The above copyright notice and this permission notice shall be */19/* included in all copies or substantial portions of the Software. */20/* */21/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */22/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */23/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */24/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */25/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */26/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */27/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */28/**************************************************************************/2930#include "dir_access_jandroid.h"3132#include "jni_utils.h"33#include "thread_jandroid.h"3435#include "core/string/print_string.h"3637jobject DirAccessJAndroid::dir_access_handler = nullptr;38jclass DirAccessJAndroid::cls = nullptr;39jmethodID DirAccessJAndroid::_dir_open = nullptr;40jmethodID DirAccessJAndroid::_dir_next = nullptr;41jmethodID DirAccessJAndroid::_dir_close = nullptr;42jmethodID DirAccessJAndroid::_dir_is_dir = nullptr;43jmethodID DirAccessJAndroid::_dir_exists = nullptr;44jmethodID DirAccessJAndroid::_file_exists = nullptr;45jmethodID DirAccessJAndroid::_get_drive_count = nullptr;46jmethodID DirAccessJAndroid::_get_drive = nullptr;47jmethodID DirAccessJAndroid::_make_dir = nullptr;48jmethodID DirAccessJAndroid::_get_space_left = nullptr;49jmethodID DirAccessJAndroid::_rename = nullptr;50jmethodID DirAccessJAndroid::_remove = nullptr;51jmethodID DirAccessJAndroid::_current_is_hidden = nullptr;5253Error DirAccessJAndroid::list_dir_begin() {54list_dir_end();55int res = dir_open(current_dir);56if (res <= 0) {57return ERR_CANT_OPEN;58}5960id = res;6162return OK;63}6465String DirAccessJAndroid::get_next() {66ERR_FAIL_COND_V(id == 0, "");67if (_dir_next) {68JNIEnv *env = get_jni_env();69ERR_FAIL_NULL_V(env, "");70jstring str = (jstring)env->CallObjectMethod(dir_access_handler, _dir_next, id);71if (!str) {72return "";73}7475String ret = jstring_to_string((jstring)str, env);76env->DeleteLocalRef((jobject)str);77return ret;78} else {79return "";80}81}8283bool DirAccessJAndroid::current_is_dir() const {84if (_dir_is_dir) {85JNIEnv *env = get_jni_env();86ERR_FAIL_NULL_V(env, false);87return env->CallBooleanMethod(dir_access_handler, _dir_is_dir, id);88} else {89return false;90}91}9293bool DirAccessJAndroid::current_is_hidden() const {94if (_current_is_hidden) {95JNIEnv *env = get_jni_env();96ERR_FAIL_NULL_V(env, false);97return env->CallBooleanMethod(dir_access_handler, _current_is_hidden, id);98}99return false;100}101102void DirAccessJAndroid::list_dir_end() {103if (id == 0) {104return;105}106107dir_close(id);108id = 0;109}110111int DirAccessJAndroid::get_drive_count() {112if (_get_drive_count) {113JNIEnv *env = get_jni_env();114ERR_FAIL_NULL_V(env, 0);115return env->CallIntMethod(dir_access_handler, _get_drive_count, get_access_type());116} else {117return 0;118}119}120121String DirAccessJAndroid::get_drive(int p_drive) {122if (_get_drive) {123JNIEnv *env = get_jni_env();124ERR_FAIL_NULL_V(env, "");125jstring j_drive = (jstring)env->CallObjectMethod(dir_access_handler, _get_drive, get_access_type(), p_drive);126if (!j_drive) {127return "";128}129130String drive = jstring_to_string(j_drive, env);131env->DeleteLocalRef(j_drive);132return drive;133} else {134return "";135}136}137138String DirAccessJAndroid::_get_root_string() const {139if (get_access_type() == ACCESS_FILESYSTEM) {140return "/";141}142return DirAccessUnix::_get_root_string();143}144145String DirAccessJAndroid::get_current_dir(bool p_include_drive) const {146String base = _get_root_path();147String bd = current_dir;148if (!base.is_empty()) {149bd = current_dir.replace_first(base, "");150}151152String root_string = _get_root_string();153if (bd.begins_with(root_string)) {154return bd;155} else if (bd.begins_with("/")) {156return root_string + bd.substr(1);157} else {158return root_string + bd;159}160}161162Error DirAccessJAndroid::change_dir(String p_dir) {163String new_dir = get_absolute_path(p_dir);164if (new_dir == current_dir) {165return OK;166}167168if (!dir_exists(new_dir)) {169return ERR_INVALID_PARAMETER;170}171172current_dir = new_dir;173return OK;174}175176String DirAccessJAndroid::get_absolute_path(String p_path) {177if (current_dir != "" && p_path == current_dir) {178return current_dir;179}180181if (p_path.is_relative_path()) {182p_path = get_current_dir().path_join(p_path);183}184185p_path = fix_path(p_path);186p_path = p_path.simplify_path();187return p_path;188}189190bool DirAccessJAndroid::file_exists(String p_file) {191if (_file_exists) {192JNIEnv *env = get_jni_env();193ERR_FAIL_NULL_V(env, false);194195String path = get_absolute_path(p_file);196jstring j_path = env->NewStringUTF(path.utf8().get_data());197bool result = env->CallBooleanMethod(dir_access_handler, _file_exists, get_access_type(), j_path);198env->DeleteLocalRef(j_path);199return result;200} else {201return false;202}203}204205bool DirAccessJAndroid::dir_exists(String p_dir) {206if (_dir_exists) {207JNIEnv *env = get_jni_env();208ERR_FAIL_NULL_V(env, false);209210String path = get_absolute_path(p_dir);211jstring j_path = env->NewStringUTF(path.utf8().get_data());212bool result = env->CallBooleanMethod(dir_access_handler, _dir_exists, get_access_type(), j_path);213env->DeleteLocalRef(j_path);214return result;215} else {216return false;217}218}219220Error DirAccessJAndroid::make_dir(String p_dir) {221// Check if the directory exists already222if (dir_exists(p_dir)) {223return ERR_ALREADY_EXISTS;224}225226if (_make_dir) {227JNIEnv *env = get_jni_env();228ERR_FAIL_NULL_V(env, ERR_UNCONFIGURED);229230String path = get_absolute_path(p_dir);231jstring j_dir = env->NewStringUTF(path.utf8().get_data());232bool result = env->CallBooleanMethod(dir_access_handler, _make_dir, get_access_type(), j_dir);233env->DeleteLocalRef(j_dir);234if (result) {235return OK;236} else {237return FAILED;238}239} else {240return ERR_UNCONFIGURED;241}242}243244Error DirAccessJAndroid::make_dir_recursive(const String &p_dir) {245Error err = make_dir(p_dir);246if (err != OK && err != ERR_ALREADY_EXISTS) {247ERR_FAIL_V_MSG(err, "Could not create directory: " + p_dir);248}249return OK;250}251252Error DirAccessJAndroid::rename(String p_from, String p_to) {253if (_rename) {254JNIEnv *env = get_jni_env();255ERR_FAIL_NULL_V(env, ERR_UNCONFIGURED);256257String from_path = get_absolute_path(p_from);258jstring j_from = env->NewStringUTF(from_path.utf8().get_data());259260String to_path = get_absolute_path(p_to);261jstring j_to = env->NewStringUTF(to_path.utf8().get_data());262263bool result = env->CallBooleanMethod(dir_access_handler, _rename, get_access_type(), j_from, j_to);264env->DeleteLocalRef(j_from);265env->DeleteLocalRef(j_to);266if (result) {267return OK;268} else {269return FAILED;270}271} else {272return ERR_UNCONFIGURED;273}274}275276Error DirAccessJAndroid::remove(String p_name) {277if (_remove) {278JNIEnv *env = get_jni_env();279ERR_FAIL_NULL_V(env, ERR_UNCONFIGURED);280281String path = get_absolute_path(p_name);282jstring j_name = env->NewStringUTF(path.utf8().get_data());283bool result = env->CallBooleanMethod(dir_access_handler, _remove, get_access_type(), j_name);284env->DeleteLocalRef(j_name);285if (result) {286return OK;287} else {288return FAILED;289}290} else {291return ERR_UNCONFIGURED;292}293}294295uint64_t DirAccessJAndroid::get_space_left() {296if (_get_space_left) {297JNIEnv *env = get_jni_env();298ERR_FAIL_NULL_V(env, 0);299return env->CallLongMethod(dir_access_handler, _get_space_left, get_access_type());300} else {301return 0;302}303}304305void DirAccessJAndroid::setup(jobject p_dir_access_handler) {306JNIEnv *env = get_jni_env();307dir_access_handler = env->NewGlobalRef(p_dir_access_handler);308309jclass c = env->GetObjectClass(dir_access_handler);310cls = (jclass)env->NewGlobalRef(c);311312_dir_open = env->GetMethodID(cls, "dirOpen", "(ILjava/lang/String;)I");313_dir_next = env->GetMethodID(cls, "dirNext", "(I)Ljava/lang/String;");314_dir_close = env->GetMethodID(cls, "dirClose", "(I)V");315_dir_is_dir = env->GetMethodID(cls, "dirIsDir", "(I)Z");316_dir_exists = env->GetMethodID(cls, "dirExists", "(ILjava/lang/String;)Z");317_file_exists = env->GetMethodID(cls, "fileExists", "(ILjava/lang/String;)Z");318_get_drive_count = env->GetMethodID(cls, "getDriveCount", "(I)I");319_get_drive = env->GetMethodID(cls, "getDrive", "(II)Ljava/lang/String;");320_make_dir = env->GetMethodID(cls, "makeDir", "(ILjava/lang/String;)Z");321_get_space_left = env->GetMethodID(cls, "getSpaceLeft", "(I)J");322_rename = env->GetMethodID(cls, "rename", "(ILjava/lang/String;Ljava/lang/String;)Z");323_remove = env->GetMethodID(cls, "remove", "(ILjava/lang/String;)Z");324_current_is_hidden = env->GetMethodID(cls, "isCurrentHidden", "(I)Z");325}326327void DirAccessJAndroid::terminate() {328JNIEnv *env = get_jni_env();329ERR_FAIL_NULL(env);330331env->DeleteGlobalRef(cls);332env->DeleteGlobalRef(dir_access_handler);333}334335DirAccessJAndroid::DirAccessJAndroid() {336}337338DirAccessJAndroid::~DirAccessJAndroid() {339list_dir_end();340}341342int DirAccessJAndroid::dir_open(String p_path) {343if (_dir_open) {344JNIEnv *env = get_jni_env();345ERR_FAIL_NULL_V(env, 0);346347String path = get_absolute_path(p_path);348jstring js = env->NewStringUTF(path.utf8().get_data());349int dirId = env->CallIntMethod(dir_access_handler, _dir_open, get_access_type(), js);350env->DeleteLocalRef(js);351return dirId;352} else {353return 0;354}355}356357void DirAccessJAndroid::dir_close(int p_id) {358if (_dir_close) {359JNIEnv *env = get_jni_env();360ERR_FAIL_NULL(env);361env->CallVoidMethod(dir_access_handler, _dir_close, p_id);362}363}364365366