Merge pull request #51719 from akien-mga/3.3-scoped-storage

This commit is contained in:
Rémi Verschelde 2021-08-16 10:56:14 +02:00 committed by GitHub
commit f66ff33b25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 126 additions and 270 deletions

View File

@ -1191,9 +1191,8 @@ bool _OS::is_keep_screen_on() const {
return OS::get_singleton()->is_keep_screen_on(); return OS::get_singleton()->is_keep_screen_on();
} }
String _OS::get_system_dir(SystemDir p_dir) const { String _OS::get_system_dir(SystemDir p_dir, bool p_shared_storage) const {
return OS::get_singleton()->get_system_dir(OS::SystemDir(p_dir), p_shared_storage);
return OS::get_singleton()->get_system_dir(OS::SystemDir(p_dir));
} }
String _OS::get_scancode_string(uint32_t p_code) const { String _OS::get_scancode_string(uint32_t p_code) const {
@ -1410,7 +1409,7 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_dynamic_memory_usage"), &_OS::get_dynamic_memory_usage); ClassDB::bind_method(D_METHOD("get_dynamic_memory_usage"), &_OS::get_dynamic_memory_usage);
ClassDB::bind_method(D_METHOD("get_user_data_dir"), &_OS::get_user_data_dir); ClassDB::bind_method(D_METHOD("get_user_data_dir"), &_OS::get_user_data_dir);
ClassDB::bind_method(D_METHOD("get_system_dir", "dir"), &_OS::get_system_dir); ClassDB::bind_method(D_METHOD("get_system_dir", "dir", "shared_storage"), &_OS::get_system_dir, DEFVAL(true));
ClassDB::bind_method(D_METHOD("get_unique_id"), &_OS::get_unique_id); ClassDB::bind_method(D_METHOD("get_unique_id"), &_OS::get_unique_id);
ClassDB::bind_method(D_METHOD("is_ok_left_and_cancel_right"), &_OS::is_ok_left_and_cancel_right); ClassDB::bind_method(D_METHOD("is_ok_left_and_cancel_right"), &_OS::is_ok_left_and_cancel_right);

View File

@ -347,7 +347,7 @@ public:
SCREEN_ORIENTATION_SENSOR, SCREEN_ORIENTATION_SENSOR,
}; };
String get_system_dir(SystemDir p_dir) const; String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const;
String get_user_data_dir() const; String get_user_data_dir() const;

View File

@ -372,8 +372,7 @@ String OS::get_resource_dir() const {
} }
// Access system-specific dirs like Documents, Downloads, etc. // Access system-specific dirs like Documents, Downloads, etc.
String OS::get_system_dir(SystemDir p_dir) const { String OS::get_system_dir(SystemDir p_dir, bool p_shared_storage) const {
return "."; return ".";
} }

View File

@ -453,7 +453,7 @@ public:
SYSTEM_DIR_RINGTONES, SYSTEM_DIR_RINGTONES,
}; };
virtual String get_system_dir(SystemDir p_dir) const; virtual String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const;
virtual Error move_to_trash(const String &p_path) { return FAILED; } virtual Error move_to_trash(const String &p_path) { return FAILED; }

View File

@ -379,9 +379,11 @@
<method name="get_system_dir" qualifiers="const"> <method name="get_system_dir" qualifiers="const">
<return type="String" /> <return type="String" />
<argument index="0" name="dir" type="int" enum="OS.SystemDir" /> <argument index="0" name="dir" type="int" enum="OS.SystemDir" />
<argument index="1" name="shared_storage" type="bool" default="true" />
<description> <description>
Returns the actual path to commonly used folders across different platforms. Available locations are specified in [enum SystemDir]. Returns the actual path to commonly used folders across different platforms. Available locations are specified in [enum SystemDir].
[b]Note:[/b] This method is implemented on Android, Linux, macOS and Windows. [b]Note:[/b] This method is implemented on Android, Linux, macOS and Windows.
[b]Note:[/b] Shared storage is implemented on Android and allows to differentiate between app specific and shared directories. Shared directories have additional restrictions on Android.
</description> </description>
</method> </method>
<method name="get_system_time_msecs" qualifiers="const"> <method name="get_system_time_msecs" qualifiers="const">

View File

@ -26,7 +26,7 @@ def get_opts():
return [ return [
("ANDROID_NDK_ROOT", "Path to the Android NDK", get_android_ndk_root()), ("ANDROID_NDK_ROOT", "Path to the Android NDK", get_android_ndk_root()),
("ANDROID_SDK_ROOT", "Path to the Android SDK", get_android_sdk_root()), ("ANDROID_SDK_ROOT", "Path to the Android SDK", get_android_sdk_root()),
("ndk_platform", 'Target platform (android-<api>, e.g. "android-18")', "android-18"), ("ndk_platform", 'Target platform (android-<api>, e.g. "android-19")', "android-19"),
EnumVariable("android_arch", "Target architecture", "armv7", ("armv7", "arm64v8", "x86", "x86_64")), EnumVariable("android_arch", "Target architecture", "armv7", ("armv7", "arm64v8", "x86", "x86_64")),
BoolVariable("android_neon", "Enable NEON support (armv7 only)", True), BoolVariable("android_neon", "Enable NEON support (armv7 only)", True),
] ]

View File

@ -852,7 +852,12 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
Vector<String> perms; Vector<String> perms;
_get_permissions(p_preset, p_give_internet, perms); _get_permissions(p_preset, p_give_internet, perms);
for (int i = 0; i < perms.size(); i++) { for (int i = 0; i < perms.size(); i++) {
manifest_text += vformat(" <uses-permission android:name=\"%s\" />\n", perms.get(i)); String permission = perms.get(i);
if (permission == "android.permission.WRITE_EXTERNAL_STORAGE" || permission == "android.permission.READ_EXTERNAL_STORAGE") {
manifest_text += vformat(" <uses-permission android:name=\"%s\" android:maxSdkVersion=\"29\" />\n", permission);
} else {
manifest_text += vformat(" <uses-permission android:name=\"%s\" />\n", permission);
}
} }
manifest_text += _get_xr_features_tag(p_preset); manifest_text += _get_xr_features_tag(p_preset);
@ -1009,7 +1014,6 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
} }
if (tname == "application" && attrname == "requestLegacyExternalStorage") { if (tname == "application" && attrname == "requestLegacyExternalStorage") {
encode_uint32(has_storage_permission ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]); encode_uint32(has_storage_permission ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]);
} }

View File

@ -1,8 +1,8 @@
ext.versions = [ ext.versions = [
androidGradlePlugin: '4.2.1', androidGradlePlugin: '4.2.2',
compileSdk : 29, compileSdk : 30,
minSdk : 18, minSdk : 19,
targetSdk : 29, targetSdk : 30,
buildTools : '30.0.3', buildTools : '30.0.3',
supportCoreUtils : '1.0.0', supportCoreUtils : '1.0.0',
kotlinVersion : '1.5.10', kotlinVersion : '1.5.10',

View File

@ -70,7 +70,6 @@ import android.os.Looper;
import android.os.Messenger; import android.os.Messenger;
import android.os.VibrationEffect; import android.os.VibrationEffect;
import android.os.Vibrator; import android.os.Vibrator;
import android.provider.Settings.Secure;
import android.view.Display; import android.view.Display;
import android.view.InputDevice; import android.view.InputDevice;
import android.view.KeyEvent; import android.view.KeyEvent;
@ -603,7 +602,6 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
final Activity activity = getActivity(); final Activity activity = getActivity();
io = new GodotIO(activity); io = new GodotIO(activity);
io.unique_id = Secure.getString(activity.getContentResolver(), Secure.ANDROID_ID);
GodotLib.io = io; GodotLib.io = io;
netUtils = new GodotNetUtils(activity); netUtils = new GodotNetUtils(activity);
mSensorManager = (SensorManager)activity.getSystemService(Context.SENSOR_SERVICE); mSensorManager = (SensorManager)activity.getSystemService(Context.SENSOR_SERVICE);

View File

@ -30,17 +30,19 @@
package org.godotengine.godot; package org.godotengine.godot;
import org.godotengine.godot.input.*; import org.godotengine.godot.input.GodotEditText;
import android.app.Activity; import android.app.Activity;
import android.content.*; import android.content.ActivityNotFoundException;
import android.content.Intent; import android.content.Intent;
import android.content.pm.ActivityInfo; import android.content.pm.ActivityInfo;
import android.content.res.AssetManager; import android.content.res.AssetManager;
import android.graphics.Point; import android.graphics.Point;
import android.media.*; import android.media.*;
import android.net.Uri; import android.net.Uri;
import android.os.*; import android.os.Build;
import android.os.Environment;
import android.provider.Settings;
import android.util.DisplayMetrics; import android.util.DisplayMetrics;
import android.util.Log; import android.util.Log;
import android.util.SparseArray; import android.util.SparseArray;
@ -49,15 +51,16 @@ import android.view.DisplayCutout;
import android.view.WindowInsets; import android.view.WindowInsets;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.util.Locale; import java.util.Locale;
// Wrapper for native library // Wrapper for native library
public class GodotIO { public class GodotIO {
private static final String TAG = GodotIO.class.getSimpleName();
AssetManager am; private final AssetManager am;
final Activity activity; private final Activity activity;
private final String uniqueId;
GodotEditText edit; GodotEditText edit;
MediaPlayer mediaPlayer; MediaPlayer mediaPlayer;
@ -70,185 +73,6 @@ public class GodotIO {
final int SCREEN_SENSOR_PORTRAIT = 5; final int SCREEN_SENSOR_PORTRAIT = 5;
final int SCREEN_SENSOR = 6; final int SCREEN_SENSOR = 6;
/////////////////////////
/// FILES
/////////////////////////
public int last_file_id = 1;
class AssetData {
public boolean eof = false;
public String path;
public InputStream is;
public int len;
public int pos;
}
SparseArray<AssetData> streams;
public int file_open(String path, boolean write) {
//System.out.printf("file_open: Attempt to Open %s\n",path);
//Log.v("MyApp", "TRYING TO OPEN FILE: " + path);
if (write)
return -1;
AssetData ad = new AssetData();
try {
ad.is = am.open(path);
} catch (Exception e) {
//System.out.printf("Exception on file_open: %s\n",path);
return -1;
}
try {
ad.len = ad.is.available();
} catch (Exception e) {
System.out.printf("Exception availabling on file_open: %s\n", path);
return -1;
}
ad.path = path;
ad.pos = 0;
++last_file_id;
streams.put(last_file_id, ad);
return last_file_id;
}
public int file_get_size(int id) {
if (streams.get(id) == null) {
System.out.printf("file_get_size: Invalid file id: %d\n", id);
return -1;
}
return streams.get(id).len;
}
public void file_seek(int id, int bytes) {
if (streams.get(id) == null) {
System.out.printf("file_get_size: Invalid file id: %d\n", id);
return;
}
//seek sucks
AssetData ad = streams.get(id);
if (bytes > ad.len)
bytes = ad.len;
if (bytes < 0)
bytes = 0;
try {
if (bytes > (int)ad.pos) {
int todo = bytes - (int)ad.pos;
while (todo > 0) {
todo -= ad.is.skip(todo);
}
ad.pos = bytes;
} else if (bytes < (int)ad.pos) {
ad.is = am.open(ad.path);
ad.pos = bytes;
int todo = bytes;
while (todo > 0) {
todo -= ad.is.skip(todo);
}
}
ad.eof = false;
} catch (IOException e) {
System.out.printf("Exception on file_seek: %s\n", e);
return;
}
}
public int file_tell(int id) {
if (streams.get(id) == null) {
System.out.printf("file_read: Can't tell eof for invalid file id: %d\n", id);
return 0;
}
AssetData ad = streams.get(id);
return ad.pos;
}
public boolean file_eof(int id) {
if (streams.get(id) == null) {
System.out.printf("file_read: Can't check eof for invalid file id: %d\n", id);
return false;
}
AssetData ad = streams.get(id);
return ad.eof;
}
public byte[] file_read(int id, int bytes) {
if (streams.get(id) == null) {
System.out.printf("file_read: Can't read invalid file id: %d\n", id);
return new byte[0];
}
AssetData ad = streams.get(id);
if (ad.pos + bytes > ad.len) {
bytes = ad.len - ad.pos;
ad.eof = true;
}
if (bytes == 0) {
return new byte[0];
}
byte[] buf1 = new byte[bytes];
int r = 0;
try {
r = ad.is.read(buf1);
} catch (IOException e) {
System.out.printf("Exception on file_read: %s\n", e);
return new byte[bytes];
}
if (r == 0) {
return new byte[0];
}
ad.pos += r;
if (r < bytes) {
byte[] buf2 = new byte[r];
for (int i = 0; i < r; i++)
buf2[i] = buf1[i];
return buf2;
} else {
return buf1;
}
}
public void file_close(int id) {
if (streams.get(id) == null) {
System.out.printf("file_close: Can't close invalid file id: %d\n", id);
return;
}
streams.remove(id);
}
///////////////////////// /////////////////////////
/// DIRECTORIES /// DIRECTORIES
///////////////////////// /////////////////////////
@ -260,9 +84,9 @@ public class GodotIO {
public String path; public String path;
} }
public int last_dir_id = 1; private int last_dir_id = 1;
SparseArray<AssetDir> dirs; private final SparseArray<AssetDir> dirs;
public int dir_open(String path) { public int dir_open(String path) {
@ -283,7 +107,6 @@ public class GodotIO {
return -1; return -1;
} }
//System.out.printf("Opened dir: %s\n",path);
++last_dir_id; ++last_dir_id;
dirs.put(last_dir_id, ad); dirs.put(last_dir_id, ad);
@ -349,9 +172,15 @@ public class GodotIO {
am = p_activity.getAssets(); am = p_activity.getAssets();
activity = p_activity; activity = p_activity;
//streams = new HashMap<Integer, AssetData>();
streams = new SparseArray<AssetData>(); dirs = new SparseArray<>();
dirs = new SparseArray<AssetDir>(); String androidId = Settings.Secure.getString(activity.getContentResolver(),
Settings.Secure.ANDROID_ID);
if (androidId == null) {
androidId = "";
}
uniqueId = androidId;
} }
///////////////////////// /////////////////////////
@ -451,7 +280,6 @@ public class GodotIO {
public int openURI(String p_uri) { public int openURI(String p_uri) {
try { try {
Log.v("MyApp", "TRYING TO OPEN URI: " + p_uri);
String path = p_uri; String path = p_uri;
String type = ""; String type = "";
if (path.startsWith("/")) { if (path.startsWith("/")) {
@ -479,8 +307,11 @@ public class GodotIO {
} }
} }
public String getDataDir() { public String getCacheDir() {
return activity.getCacheDir().getAbsolutePath();
}
public String getDataDir() {
return activity.getFilesDir().getAbsolutePath(); return activity.getFilesDir().getAbsolutePath();
} }
@ -612,53 +443,54 @@ public class GodotIO {
public static final int SYSTEM_DIR_PICTURES = 6; public static final int SYSTEM_DIR_PICTURES = 6;
public static final int SYSTEM_DIR_RINGTONES = 7; public static final int SYSTEM_DIR_RINGTONES = 7;
public String getSystemDir(int idx) { public String getSystemDir(int idx, boolean shared_storage) {
String what;
String what = "";
switch (idx) { switch (idx) {
case SYSTEM_DIR_DESKTOP: { case SYSTEM_DIR_DESKTOP:
//what=Environment.DIRECTORY_DOCUMENTS; default: {
what = Environment.DIRECTORY_DOWNLOADS; what = null; // This leads to the app specific external root directory.
} break; } break;
case SYSTEM_DIR_DCIM: { case SYSTEM_DIR_DCIM: {
what = Environment.DIRECTORY_DCIM; what = Environment.DIRECTORY_DCIM;
} break;
} break;
case SYSTEM_DIR_DOCUMENTS: { case SYSTEM_DIR_DOCUMENTS: {
what = Environment.DIRECTORY_DOWNLOADS; what = Environment.DIRECTORY_DOCUMENTS;
//what=Environment.DIRECTORY_DOCUMENTS;
} break; } break;
case SYSTEM_DIR_DOWNLOADS: { case SYSTEM_DIR_DOWNLOADS: {
what = Environment.DIRECTORY_DOWNLOADS; what = Environment.DIRECTORY_DOWNLOADS;
} break; } break;
case SYSTEM_DIR_MOVIES: { case SYSTEM_DIR_MOVIES: {
what = Environment.DIRECTORY_MOVIES; what = Environment.DIRECTORY_MOVIES;
} break; } break;
case SYSTEM_DIR_MUSIC: { case SYSTEM_DIR_MUSIC: {
what = Environment.DIRECTORY_MUSIC; what = Environment.DIRECTORY_MUSIC;
} break; } break;
case SYSTEM_DIR_PICTURES: { case SYSTEM_DIR_PICTURES: {
what = Environment.DIRECTORY_PICTURES; what = Environment.DIRECTORY_PICTURES;
} break; } break;
case SYSTEM_DIR_RINGTONES: { case SYSTEM_DIR_RINGTONES: {
what = Environment.DIRECTORY_RINGTONES; what = Environment.DIRECTORY_RINGTONES;
} break; } break;
} }
if (what.equals("")) if (shared_storage) {
return ""; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
return Environment.getExternalStoragePublicDirectory(what).getAbsolutePath(); Log.w(TAG, "Shared storage access is limited on Android 10 and higher.");
}
return Environment.getExternalStoragePublicDirectory(what).getAbsolutePath();
} else {
return activity.getExternalFilesDir(what).getAbsolutePath();
}
} }
protected static final String PREFS_FILE = "device_id.xml";
protected static final String PREFS_DEVICE_ID = "device_id";
public static String unique_id = "";
public String getUniqueID() { public String getUniqueID() {
return uniqueId;
return unique_id;
} }
} }

View File

@ -48,6 +48,7 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc
} }
_open_URI = p_env->GetMethodID(cls, "openURI", "(Ljava/lang/String;)I"); _open_URI = p_env->GetMethodID(cls, "openURI", "(Ljava/lang/String;)I");
_get_cache_dir = p_env->GetMethodID(cls, "getCacheDir", "()Ljava/lang/String;");
_get_data_dir = p_env->GetMethodID(cls, "getDataDir", "()Ljava/lang/String;"); _get_data_dir = p_env->GetMethodID(cls, "getDataDir", "()Ljava/lang/String;");
_get_locale = p_env->GetMethodID(cls, "getLocale", "()Ljava/lang/String;"); _get_locale = p_env->GetMethodID(cls, "getLocale", "()Ljava/lang/String;");
_get_model = p_env->GetMethodID(cls, "getModel", "()Ljava/lang/String;"); _get_model = p_env->GetMethodID(cls, "getModel", "()Ljava/lang/String;");
@ -58,7 +59,7 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc
_hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V"); _hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V");
_set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V"); _set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V");
_get_screen_orientation = p_env->GetMethodID(cls, "getScreenOrientation", "()I"); _get_screen_orientation = p_env->GetMethodID(cls, "getScreenOrientation", "()I");
_get_system_dir = p_env->GetMethodID(cls, "getSystemDir", "(I)Ljava/lang/String;"); _get_system_dir = p_env->GetMethodID(cls, "getSystemDir", "(IZ)Ljava/lang/String;");
_play_video = p_env->GetMethodID(cls, "playVideo", "(Ljava/lang/String;)V"); _play_video = p_env->GetMethodID(cls, "playVideo", "(Ljava/lang/String;)V");
_is_video_playing = p_env->GetMethodID(cls, "isVideoPlaying", "()Z"); _is_video_playing = p_env->GetMethodID(cls, "isVideoPlaying", "()Z");
_pause_video = p_env->GetMethodID(cls, "pauseVideo", "()V"); _pause_video = p_env->GetMethodID(cls, "pauseVideo", "()V");
@ -85,6 +86,17 @@ Error GodotIOJavaWrapper::open_uri(const String &p_uri) {
} }
} }
String GodotIOJavaWrapper::get_cache_dir() {
if (_get_cache_dir) {
JNIEnv *env = get_jni_env();
ERR_FAIL_COND_V(env == nullptr, String());
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_cache_dir);
return jstring_to_string(s, env);
} else {
return String();
}
}
String GodotIOJavaWrapper::get_user_data_dir() { String GodotIOJavaWrapper::get_user_data_dir() {
if (_get_data_dir) { if (_get_data_dir) {
JNIEnv *env = get_jni_env(); JNIEnv *env = get_jni_env();
@ -192,11 +204,11 @@ int GodotIOJavaWrapper::get_screen_orientation() const {
} }
} }
String GodotIOJavaWrapper::get_system_dir(int p_dir) { String GodotIOJavaWrapper::get_system_dir(int p_dir, bool p_shared_storage) {
if (_get_system_dir) { if (_get_system_dir) {
JNIEnv *env = get_jni_env(); JNIEnv *env = get_jni_env();
ERR_FAIL_COND_V(env == nullptr, String(".")); ERR_FAIL_COND_V(env == nullptr, String("."));
jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_system_dir, p_dir); jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_system_dir, p_dir, p_shared_storage);
return jstring_to_string(s, env); return jstring_to_string(s, env);
} else { } else {
return String("."); return String(".");

View File

@ -46,6 +46,7 @@ private:
jclass cls; jclass cls;
jmethodID _open_URI = 0; jmethodID _open_URI = 0;
jmethodID _get_cache_dir = 0;
jmethodID _get_data_dir = 0; jmethodID _get_data_dir = 0;
jmethodID _get_locale = 0; jmethodID _get_locale = 0;
jmethodID _get_model = 0; jmethodID _get_model = 0;
@ -69,6 +70,7 @@ public:
jobject get_instance(); jobject get_instance();
Error open_uri(const String &p_uri); Error open_uri(const String &p_uri);
String get_cache_dir();
String get_user_data_dir(); String get_user_data_dir();
String get_locale(); String get_locale();
String get_model(); String get_model();
@ -82,7 +84,7 @@ public:
void set_vk_height(int p_height); void set_vk_height(int p_height);
void set_screen_orientation(int p_orient); void set_screen_orientation(int p_orient);
int get_screen_orientation() const; int get_screen_orientation() const;
String get_system_dir(int p_dir); String get_system_dir(int p_dir, bool p_shared_storage);
void play_video(const String &p_path); void play_video(const String &p_path);
bool is_video_playing(); bool is_video_playing();
void pause_video(); void pause_video();

View File

@ -51,6 +51,23 @@
#include "java_godot_io_wrapper.h" #include "java_godot_io_wrapper.h"
#include "java_godot_wrapper.h" #include "java_godot_wrapper.h"
String _remove_symlink(const String &dir) {
// Workaround for Android 6.0+ using a symlink.
// Save the current directory.
char current_dir_name[2048];
getcwd(current_dir_name, 2048);
// Change directory to the external data directory.
chdir(dir.utf8().get_data());
// Get the actual directory without the potential symlink.
char dir_name_wihout_symlink[2048];
getcwd(dir_name_wihout_symlink, 2048);
// Convert back to a String.
String dir_without_symlink(dir_name_wihout_symlink);
// Restore original current directory.
chdir(current_dir_name);
return dir_without_symlink;
}
class AndroidLogger : public Logger { class AndroidLogger : public Logger {
public: public:
virtual void logv(const char *p_format, va_list p_list, bool p_err) { virtual void logv(const char *p_format, va_list p_list, bool p_err) {
@ -802,34 +819,28 @@ int OS_Android::get_screen_dpi(int p_screen) const {
return godot_io_java->get_screen_dpi(); return godot_io_java->get_screen_dpi();
} }
String OS_Android::get_user_data_dir() const { String OS_Android::get_data_path() const {
return get_user_data_dir();
}
String OS_Android::get_user_data_dir() const {
if (data_dir_cache != String()) if (data_dir_cache != String())
return data_dir_cache; return data_dir_cache;
String data_dir = godot_io_java->get_user_data_dir(); String data_dir = godot_io_java->get_user_data_dir();
if (data_dir != "") { if (data_dir != "") {
data_dir_cache = _remove_symlink(data_dir);
//store current dir
char real_current_dir_name[2048];
getcwd(real_current_dir_name, 2048);
//go to data dir
chdir(data_dir.utf8().get_data());
//get actual data dir, so we resolve potential symlink (Android 6.0+ seems to use symlink)
char data_current_dir_name[2048];
getcwd(data_current_dir_name, 2048);
//cache by parsing utf8
data_dir_cache.parse_utf8(data_current_dir_name);
//restore original dir so we don't mess things up
chdir(real_current_dir_name);
return data_dir_cache; return data_dir_cache;
} }
return ".";
}
String OS_Android::get_cache_path() const {
String cache_dir = godot_io_java->get_cache_dir();
if (cache_dir != "") {
cache_dir = _remove_symlink(cache_dir);
return cache_dir;
}
return "."; return ".";
} }
@ -869,9 +880,8 @@ void OS_Android::native_video_pause() {
godot_io_java->pause_video(); godot_io_java->pause_video();
} }
String OS_Android::get_system_dir(SystemDir p_dir) const { String OS_Android::get_system_dir(SystemDir p_dir, bool p_shared_storage) const {
return godot_io_java->get_system_dir(p_dir, p_shared_storage);
return godot_io_java->get_system_dir(p_dir);
} }
void OS_Android::native_video_stop() { void OS_Android::native_video_stop() {

View File

@ -188,6 +188,8 @@ public:
virtual Error shell_open(String p_uri); virtual Error shell_open(String p_uri);
virtual String get_user_data_dir() const; virtual String get_user_data_dir() const;
virtual String get_data_path() const;
virtual String get_cache_path() const;
virtual String get_resource_dir() const; virtual String get_resource_dir() const;
virtual String get_locale() const; virtual String get_locale() const;
virtual void set_clipboard(const String &p_text); virtual void set_clipboard(const String &p_text);
@ -197,7 +199,7 @@ public:
virtual String get_unique_id() const; virtual String get_unique_id() const;
virtual String get_system_dir(SystemDir p_dir) const; virtual String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const;
void process_accelerometer(const Vector3 &p_accelerometer); void process_accelerometer(const Vector3 &p_accelerometer);
void process_gravity(const Vector3 &p_gravity); void process_gravity(const Vector3 &p_gravity);

View File

@ -226,7 +226,7 @@ public:
virtual String get_bundle_resource_dir() const; virtual String get_bundle_resource_dir() const;
virtual String get_godot_dir_name() const; virtual String get_godot_dir_name() const;
virtual String get_system_dir(SystemDir p_dir) const; virtual String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const;
virtual bool can_draw() const; virtual bool can_draw() const;

View File

@ -2297,8 +2297,7 @@ String OS_OSX::get_godot_dir_name() const {
return String(VERSION_SHORT_NAME).capitalize(); return String(VERSION_SHORT_NAME).capitalize();
} }
String OS_OSX::get_system_dir(SystemDir p_dir) const { String OS_OSX::get_system_dir(SystemDir p_dir, bool p_shared_storage) const {
NSSearchPathDirectory id; NSSearchPathDirectory id;
bool found = true; bool found = true;

View File

@ -258,8 +258,7 @@ String OS_Server::get_cache_path() const {
} }
} }
String OS_Server::get_system_dir(SystemDir p_dir) const { String OS_Server::get_system_dir(SystemDir p_dir, bool p_shared_storage) const {
String xdgparam; String xdgparam;
switch (p_dir) { switch (p_dir) {

View File

@ -120,7 +120,7 @@ public:
virtual String get_data_path() const; virtual String get_data_path() const;
virtual String get_cache_path() const; virtual String get_cache_path() const;
virtual String get_system_dir(SystemDir p_dir) const; virtual String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const;
void disable_crash_handler(); void disable_crash_handler();
bool is_disable_crash_handler() const; bool is_disable_crash_handler() const;

View File

@ -3486,8 +3486,7 @@ String OS_Windows::get_godot_dir_name() const {
return String(VERSION_SHORT_NAME).capitalize(); return String(VERSION_SHORT_NAME).capitalize();
} }
String OS_Windows::get_system_dir(SystemDir p_dir) const { String OS_Windows::get_system_dir(SystemDir p_dir, bool p_shared_storage) const {
KNOWNFOLDERID id; KNOWNFOLDERID id;
switch (p_dir) { switch (p_dir) {

View File

@ -535,7 +535,7 @@ public:
virtual String get_cache_path() const; virtual String get_cache_path() const;
virtual String get_godot_dir_name() const; virtual String get_godot_dir_name() const;
virtual String get_system_dir(SystemDir p_dir) const; virtual String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const;
virtual String get_user_data_dir() const; virtual String get_user_data_dir() const;
virtual String get_unique_id() const; virtual String get_unique_id() const;

View File

@ -3237,8 +3237,7 @@ String OS_X11::get_cache_path() const {
} }
} }
String OS_X11::get_system_dir(SystemDir p_dir) const { String OS_X11::get_system_dir(SystemDir p_dir, bool p_shared_storage) const {
String xdgparam; String xdgparam;
switch (p_dir) { switch (p_dir) {

View File

@ -279,7 +279,7 @@ public:
virtual String get_data_path() const; virtual String get_data_path() const;
virtual String get_cache_path() const; virtual String get_cache_path() const;
virtual String get_system_dir(SystemDir p_dir) const; virtual String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const;
virtual Error shell_open(String p_uri); virtual Error shell_open(String p_uri);