diff options
23 files changed, 121 insertions, 263 deletions
diff --git a/core/core_bind.cpp b/core/core_bind.cpp index f3f51e57ee..e1d595e98c 100644 --- a/core/core_bind.cpp +++ b/core/core_bind.cpp @@ -456,10 +456,6 @@ String _OS::get_user_data_dir() const {  	return OS::get_singleton()->get_user_data_dir();  } -String _OS::get_external_data_dir() const { -	return OS::get_singleton()->get_external_data_dir(); -} -  String _OS::get_config_dir() const {  	// Exposed as `get_config_dir()` instead of `get_config_path()` for consistency with other exposed OS methods.  	return OS::get_singleton()->get_config_path(); @@ -483,8 +479,8 @@ bool _OS::is_debug_build() const {  #endif  } -String _OS::get_system_dir(SystemDir p_dir) const { -	return OS::get_singleton()->get_system_dir(OS::SystemDir(p_dir)); +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);  }  String _OS::get_keycode_string(uint32_t p_code) const { @@ -567,8 +563,7 @@ void _OS::_bind_methods() {  	ClassDB::bind_method(D_METHOD("get_static_memory_peak_usage"), &_OS::get_static_memory_peak_usage);  	ClassDB::bind_method(D_METHOD("get_user_data_dir"), &_OS::get_user_data_dir); -	ClassDB::bind_method(D_METHOD("get_external_data_dir"), &_OS::get_external_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_config_dir"), &_OS::get_config_dir);  	ClassDB::bind_method(D_METHOD("get_data_dir"), &_OS::get_data_dir);  	ClassDB::bind_method(D_METHOD("get_cache_dir"), &_OS::get_cache_dir); diff --git a/core/core_bind.h b/core/core_bind.h index 9060aff340..94e8ab2a34 100644 --- a/core/core_bind.h +++ b/core/core_bind.h @@ -229,10 +229,9 @@ public:  		SYSTEM_DIR_RINGTONES,  	}; -	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_external_data_dir() const;  	String get_config_dir() const;  	String get_data_dir() const;  	String get_cache_dir() const; diff --git a/core/os/os.cpp b/core/os/os.cpp index 76a6da51e1..63390919f4 100644 --- a/core/os/os.cpp +++ b/core/os/os.cpp @@ -277,18 +277,13 @@ String OS::get_user_data_dir() const {  	return ".";  } -// Android OS path to app's external data storage -String OS::get_external_data_dir() const { -	return get_user_data_dir(); -}; -  // Absolute path to res://  String OS::get_resource_dir() const {  	return ProjectSettings::get_singleton()->get_resource_path();  }  // 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 ".";  } diff --git a/core/os/os.h b/core/os/os.h index 0466d94acd..55b21266fc 100644 --- a/core/os/os.h +++ b/core/os/os.h @@ -250,7 +250,6 @@ public:  	virtual String get_bundle_resource_dir() const;  	virtual String get_user_data_dir() const; -	virtual String get_external_data_dir() const;  	virtual String get_resource_dir() const;  	enum SystemDir { @@ -264,7 +263,7 @@ public:  		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; } diff --git a/doc/classes/OS.xml b/doc/classes/OS.xml index e5d45189c7..757730f6c8 100644 --- a/doc/classes/OS.xml +++ b/doc/classes/OS.xml @@ -197,12 +197,6 @@  				Returns the path to the current engine executable.  			</description>  		</method> -		<method name="get_external_data_dir" qualifiers="const"> -			<return type="String" /> -			<description> -				On Android, returns the absolute directory path where user data can be written to external storage if available. On all other platforms, this will return the same location as [method get_user_data_dir]. -			</description> -		</method>  		<method name="get_granted_permissions" qualifiers="const">  			<return type="PackedStringArray" />  			<description> @@ -270,9 +264,11 @@  		<method name="get_system_dir" qualifiers="const">  			<return type="String" />  			<argument index="0" name="dir" type="int" enum="OS.SystemDir" /> +			<argument index="1" name="shared_storage" type="bool" default="true" />  			<description>  				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] Shared storage is implemented on Android and allows to differentiate between app specific and shared directories. Shared directories have additional restrictions on Android.  			</description>  		</method>  		<method name="get_thread_caller_id" qualifiers="const"> diff --git a/platform/android/export/export_plugin.cpp b/platform/android/export/export_plugin.cpp index 17ee173855..8ed2d4e60a 100644 --- a/platform/android/export/export_plugin.cpp +++ b/platform/android/export/export_plugin.cpp @@ -717,6 +717,10 @@ Error EditorExportPlatformAndroid::copy_gradle_so(void *p_userdata, const Shared  	return OK;  } +bool EditorExportPlatformAndroid::_has_storage_permission(const Vector<String> &p_permissions) { +	return p_permissions.find("android.permission.READ_EXTERNAL_STORAGE") != -1 || p_permissions.find("android.permission.WRITE_EXTERNAL_STORAGE") != -1; +} +  void EditorExportPlatformAndroid::_get_permissions(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, Vector<String> &r_permissions) {  	const char **aperms = android_perms;  	while (*aperms) { @@ -763,12 +767,17 @@ void EditorExportPlatformAndroid::_write_tmp_manifest(const Ref<EditorExportPres  	Vector<String> perms;  	_get_permissions(p_preset, p_give_internet, perms);  	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_instrumentation_tag(p_preset); -	manifest_text += _get_application_tag(p_preset); +	manifest_text += _get_application_tag(p_preset, _has_storage_permission(perms));  	manifest_text += "</manifest>\n";  	String manifest_path = vformat("res://android/build/src/%s/AndroidManifest.xml", (p_debug ? "debug" : "release")); @@ -824,6 +833,7 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p  	Vector<String> perms;  	// Write permissions into the perms variable.  	_get_permissions(p_preset, p_give_internet, perms); +	bool has_storage_permission = _has_storage_permission(perms);  	while (ofs < (uint32_t)p_manifest.size()) {  		uint32_t chunk = decode_uint32(&p_manifest[ofs]); @@ -913,6 +923,10 @@ void EditorExportPlatformAndroid::_fix_manifest(const Ref<EditorExportPreset> &p  						}  					} +					if (tname == "application" && attrname == "requestLegacyExternalStorage") { +						encode_uint32(has_storage_permission ? 0xFFFFFFFF : 0, &p_manifest.write[iofs + 16]); +					} +  					if (tname == "application" && attrname == "allowBackup") {  						encode_uint32(backup_allowed, &p_manifest.write[iofs + 16]);  					} diff --git a/platform/android/export/export_plugin.h b/platform/android/export/export_plugin.h index 909428c2fe..b061ee4e04 100644 --- a/platform/android/export/export_plugin.h +++ b/platform/android/export/export_plugin.h @@ -134,6 +134,8 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {  	static Error copy_gradle_so(void *p_userdata, const SharedObject &p_so); +	bool _has_storage_permission(const Vector<String> &p_permissions); +  	void _get_permissions(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, Vector<String> &r_permissions);  	void _write_tmp_manifest(const Ref<EditorExportPreset> &p_preset, bool p_give_internet, bool p_debug); diff --git a/platform/android/export/gradle_export_util.cpp b/platform/android/export/gradle_export_util.cpp index 76512226bf..b9e28a7937 100644 --- a/platform/android/export/gradle_export_util.cpp +++ b/platform/android/export/gradle_export_util.cpp @@ -235,18 +235,20 @@ String _get_activity_tag(const Ref<EditorExportPreset> &p_preset) {  	return manifest_activity_text;  } -String _get_application_tag(const Ref<EditorExportPreset> &p_preset) { +String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_storage_permission) {  	String manifest_application_text = vformat(  			"    <application android:label=\"@string/godot_project_name_string\"\n"  			"        android:allowBackup=\"%s\"\n"  			"        android:icon=\"@mipmap/icon\"\n"  			"        android:isGame=\"%s\"\n"  			"        android:hasFragileUserData=\"%s\"\n" -			"        tools:replace=\"android:allowBackup,android:isGame,android:hasFragileUserData\"\n" +			"        android:requestLegacyExternalStorage=\"%s\"\n" +			"        tools:replace=\"android:allowBackup,android:isGame,android:hasFragileUserData,android:requestLegacyExternalStorage\"\n"  			"        tools:ignore=\"GoogleAppIndexingWarning\">\n\n",  			bool_to_string(p_preset->get("user_data_backup/allow")),  			bool_to_string(p_preset->get("package/classify_as_game")), -			bool_to_string(p_preset->get("package/retain_data_on_uninstall"))); +			bool_to_string(p_preset->get("package/retain_data_on_uninstall")), +			bool_to_string(p_has_storage_permission));  	manifest_application_text += _get_activity_tag(p_preset);  	manifest_application_text += "    </application>\n"; diff --git a/platform/android/export/gradle_export_util.h b/platform/android/export/gradle_export_util.h index 44e9a1727d..8a93c25d79 100644 --- a/platform/android/export/gradle_export_util.h +++ b/platform/android/export/gradle_export_util.h @@ -81,6 +81,6 @@ String _get_instrumentation_tag(const Ref<EditorExportPreset> &p_preset);  String _get_activity_tag(const Ref<EditorExportPreset> &p_preset); -String _get_application_tag(const Ref<EditorExportPreset> &p_preset); +String _get_application_tag(const Ref<EditorExportPreset> &p_preset, bool p_has_storage_permission);  #endif //GODOT_GRADLE_EXPORT_UTIL_H diff --git a/platform/android/java/app/AndroidManifest.xml b/platform/android/java/app/AndroidManifest.xml index 467a0dc3c0..00e01884cf 100644 --- a/platform/android/java/app/AndroidManifest.xml +++ b/platform/android/java/app/AndroidManifest.xml @@ -22,6 +22,7 @@          android:icon="@mipmap/icon"          android:isGame="true"          android:hasFragileUserData="false" +        android:requestLegacyExternalStorage="false"          tools:ignore="GoogleAppIndexingWarning" >          <!-- Records the version of the Godot editor used for building --> diff --git a/platform/android/java/app/config.gradle b/platform/android/java/app/config.gradle index 81fc87b7ef..fad64c675f 100644 --- a/platform/android/java/app/config.gradle +++ b/platform/android/java/app/config.gradle @@ -1,8 +1,8 @@  ext.versions = [ -    androidGradlePlugin: '4.2.1', -    compileSdk         : 29, -    minSdk             : 18, -    targetSdk          : 29, +    androidGradlePlugin: '4.2.2', +    compileSdk         : 30, +    minSdk             : 19, +    targetSdk          : 30,      buildTools         : '30.0.3',      supportCoreUtils   : '1.0.0',      kotlinVersion      : '1.5.10', diff --git a/platform/android/java/lib/src/org/godotengine/godot/Godot.java b/platform/android/java/lib/src/org/godotengine/godot/Godot.java index 76751a886c..317175858b 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java @@ -49,7 +49,6 @@ import android.content.ClipData;  import android.content.ClipboardManager;  import android.content.ComponentName;  import android.content.Context; -import android.content.DialogInterface;  import android.content.Intent;  import android.content.SharedPreferences;  import android.content.SharedPreferences.Editor; @@ -68,15 +67,12 @@ import android.os.Environment;  import android.os.Messenger;  import android.os.VibrationEffect;  import android.os.Vibrator; -import android.provider.Settings.Secure;  import android.view.Display; -import android.view.KeyEvent;  import android.view.LayoutInflater;  import android.view.Surface;  import android.view.View;  import android.view.ViewGroup;  import android.view.ViewGroup.LayoutParams; -import android.view.ViewTreeObserver;  import android.view.Window;  import android.view.WindowManager;  import android.widget.Button; @@ -471,7 +467,6 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC  		final Activity activity = getActivity();  		io = new GodotIO(activity); -		io.unique_id = Secure.getString(activity.getContentResolver(), Secure.ANDROID_ID);  		GodotLib.io = io;  		netUtils = new GodotNetUtils(activity);  		mSensorManager = (SensorManager)activity.getSystemService(Context.SENSOR_SERVICE); diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java index 66882e8e72..d85d88ec6c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java @@ -30,15 +30,19 @@  package org.godotengine.godot; -import org.godotengine.godot.input.*; +import org.godotengine.godot.input.GodotEditText;  import android.app.Activity; -import android.content.*; +import android.content.ActivityNotFoundException; +import android.content.Intent;  import android.content.pm.ActivityInfo;  import android.content.res.AssetManager;  import android.graphics.Point;  import android.net.Uri; -import android.os.*; +import android.os.Build; +import android.os.Environment; +import android.provider.Settings; +import android.text.TextUtils;  import android.util.DisplayMetrics;  import android.util.Log;  import android.util.SparseArray; @@ -47,14 +51,16 @@ import android.view.DisplayCutout;  import android.view.WindowInsets;  import java.io.IOException; -import java.io.InputStream;  import java.util.Locale;  // Wrapper for native library  public class GodotIO { -	AssetManager am; -	final Activity activity; +	private static final String TAG = GodotIO.class.getSimpleName(); + +	private final AssetManager am; +	private final Activity activity; +	private final String uniqueId;  	GodotEditText edit;  	final int SCREEN_LANDSCAPE = 0; @@ -66,167 +72,6 @@ public class GodotIO {  	final int SCREEN_SENSOR = 6;  	///////////////////////// -	/// FILES -	///////////////////////// - -	public int last_file_id = 1; - -	static 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  	///////////////////////// @@ -236,9 +81,9 @@ public class GodotIO {  		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) {  		AssetDir ad = new AssetDir(); @@ -257,7 +102,6 @@ public class GodotIO {  			return -1;  		} -		//System.out.printf("Opened dir: %s\n",path);  		++last_dir_id;  		dirs.put(last_dir_id, ad); @@ -320,9 +164,14 @@ public class GodotIO {  	GodotIO(Activity p_activity) {  		am = p_activity.getAssets();  		activity = p_activity; -		//streams = new HashMap<Integer, AssetData>(); -		streams = new SparseArray<>();  		dirs = new SparseArray<>(); +		String androidId = Settings.Secure.getString(activity.getContentResolver(), +				Settings.Secure.ANDROID_ID); +		if (androidId == null) { +			androidId = ""; +		} + +		uniqueId = androidId;  	}  	///////////////////////// @@ -331,7 +180,6 @@ public class GodotIO {  	public int openURI(String p_uri) {  		try { -			Log.v("MyApp", "TRYING TO OPEN URI: " + p_uri);  			String path = p_uri;  			String type = "";  			if (path.startsWith("/")) { @@ -357,12 +205,12 @@ public class GodotIO {  		}  	} -	public String getDataDir() { -		return activity.getFilesDir().getAbsolutePath(); +	public String getCacheDir() { +		return activity.getCacheDir().getAbsolutePath();  	} -	public String getExternalDataDir() { -		return activity.getExternalFilesDir(null).getAbsolutePath(); +	public String getDataDir() { +		return activity.getFilesDir().getAbsolutePath();  	}  	public String getLocale() { @@ -456,51 +304,58 @@ public class GodotIO {  	public static final int SYSTEM_DIR_PICTURES = 6;  	public static final int SYSTEM_DIR_RINGTONES = 7; -	public String getSystemDir(int idx) { -		String what = ""; +	public String getSystemDir(int idx, boolean shared_storage) { +		String what;  		switch (idx) { -			case SYSTEM_DIR_DESKTOP: { -				//what=Environment.DIRECTORY_DOCUMENTS; -				what = Environment.DIRECTORY_DOWNLOADS; +			case SYSTEM_DIR_DESKTOP: +			default: { +				what = null; // This leads to the app specific external root directory.  			} break; +  			case SYSTEM_DIR_DCIM: {  				what = Environment.DIRECTORY_DCIM; -  			} break; +  			case SYSTEM_DIR_DOCUMENTS: { -				what = Environment.DIRECTORY_DOWNLOADS; -				//what=Environment.DIRECTORY_DOCUMENTS; +				what = Environment.DIRECTORY_DOCUMENTS;  			} break; +  			case SYSTEM_DIR_DOWNLOADS: {  				what = Environment.DIRECTORY_DOWNLOADS; -  			} break; +  			case SYSTEM_DIR_MOVIES: {  				what = Environment.DIRECTORY_MOVIES; -  			} break; +  			case SYSTEM_DIR_MUSIC: {  				what = Environment.DIRECTORY_MUSIC;  			} break; +  			case SYSTEM_DIR_PICTURES: {  				what = Environment.DIRECTORY_PICTURES;  			} break; +  			case SYSTEM_DIR_RINGTONES: {  				what = Environment.DIRECTORY_RINGTONES; -  			} break;  		} -		if (what.equals("")) -			return ""; -		return Environment.getExternalStoragePublicDirectory(what).getAbsolutePath(); +		if (shared_storage) { +			if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { +				Log.w(TAG, "Shared storage access is limited on Android 10 and higher."); +			} +			if (TextUtils.isEmpty(what)) { +				return Environment.getExternalStorageDirectory().getAbsolutePath(); +			} else { +				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() { -		return unique_id; +		return uniqueId;  	}  } diff --git a/platform/android/java_godot_io_wrapper.cpp b/platform/android/java_godot_io_wrapper.cpp index 5e99135498..5cd2c382d2 100644 --- a/platform/android/java_godot_io_wrapper.cpp +++ b/platform/android/java_godot_io_wrapper.cpp @@ -48,8 +48,8 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc  		}  		_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_external_data_dir = p_env->GetMethodID(cls, "getExternalDataDir", "()Ljava/lang/String;");  		_get_locale = p_env->GetMethodID(cls, "getLocale", "()Ljava/lang/String;");  		_get_model = p_env->GetMethodID(cls, "getModel", "()Ljava/lang/String;");  		_get_screen_DPI = p_env->GetMethodID(cls, "getScreenDPI", "()I"); @@ -59,7 +59,7 @@ GodotIOJavaWrapper::GodotIOJavaWrapper(JNIEnv *p_env, jobject p_godot_io_instanc  		_hide_keyboard = p_env->GetMethodID(cls, "hideKeyboard", "()V");  		_set_screen_orientation = p_env->GetMethodID(cls, "setScreenOrientation", "(I)V");  		_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;");  	}  } @@ -82,22 +82,22 @@ Error GodotIOJavaWrapper::open_uri(const String &p_uri) {  	}  } -String GodotIOJavaWrapper::get_user_data_dir() { -	if (_get_data_dir) { +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_data_dir); +		jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_cache_dir);  		return jstring_to_string(s, env);  	} else {  		return String();  	}  } -String GodotIOJavaWrapper::get_external_data_dir() { -	if (_get_external_data_dir) { +String GodotIOJavaWrapper::get_user_data_dir() { +	if (_get_data_dir) {  		JNIEnv *env = get_jni_env();  		ERR_FAIL_COND_V(env == nullptr, String()); -		jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_external_data_dir); +		jstring s = (jstring)env->CallObjectMethod(godot_io_instance, _get_data_dir);  		return jstring_to_string(s, env);  	} else {  		return String(); @@ -200,11 +200,11 @@ int GodotIOJavaWrapper::get_screen_orientation() {  	}  } -String GodotIOJavaWrapper::get_system_dir(int p_dir) { +String GodotIOJavaWrapper::get_system_dir(int p_dir, bool p_shared_storage) {  	if (_get_system_dir) {  		JNIEnv *env = get_jni_env();  		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);  	} else {  		return String("."); diff --git a/platform/android/java_godot_io_wrapper.h b/platform/android/java_godot_io_wrapper.h index e4c0a4b2c7..8f6d7f813f 100644 --- a/platform/android/java_godot_io_wrapper.h +++ b/platform/android/java_godot_io_wrapper.h @@ -46,8 +46,8 @@ private:  	jclass cls;  	jmethodID _open_URI = 0; +	jmethodID _get_cache_dir = 0;  	jmethodID _get_data_dir = 0; -	jmethodID _get_external_data_dir = 0;  	jmethodID _get_locale = 0;  	jmethodID _get_model = 0;  	jmethodID _get_screen_DPI = 0; @@ -66,8 +66,8 @@ public:  	jobject get_instance();  	Error open_uri(const String &p_uri); +	String get_cache_dir();  	String get_user_data_dir(); -	String get_external_data_dir();  	String get_locale();  	String get_model();  	int get_screen_dpi(); @@ -80,7 +80,7 @@ public:  	void set_vk_height(int p_height);  	void set_screen_orientation(int p_orient);  	int get_screen_orientation(); -	String get_system_dir(int p_dir); +	String get_system_dir(int p_dir, bool p_shared_storage);  };  #endif /* !JAVA_GODOT_IO_WRAPPER_H */ diff --git a/platform/android/os_android.cpp b/platform/android/os_android.cpp index c2e12442b3..21fb31d991 100644 --- a/platform/android/os_android.cpp +++ b/platform/android/os_android.cpp @@ -213,6 +213,10 @@ String OS_Android::get_model_name() const {  	return OS_Unix::get_model_name();  } +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())  		return data_dir_cache; @@ -225,11 +229,11 @@ String OS_Android::get_user_data_dir() const {  	return ".";  } -String OS_Android::get_external_data_dir() const { -	String data_dir = godot_io_java->get_external_data_dir(); -	if (data_dir != "") { -		data_dir = _remove_symlink(data_dir); -		return data_dir; +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 ".";  } @@ -242,8 +246,8 @@ String OS_Android::get_unique_id() const {  	return OS::get_unique_id();  } -String OS_Android::get_system_dir(SystemDir p_dir) const { -	return godot_io_java->get_system_dir(p_dir); +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);  }  void OS_Android::set_display_size(const Size2i &p_size) { diff --git a/platform/android/os_android.h b/platform/android/os_android.h index a5b995a775..c938297821 100644 --- a/platform/android/os_android.h +++ b/platform/android/os_android.h @@ -110,14 +110,15 @@ public:  	virtual Error shell_open(String p_uri) override;  	virtual String get_user_data_dir() const override; -	virtual String get_external_data_dir() const override; +	virtual String get_data_path() const override; +	virtual String get_cache_path() const override;  	virtual String get_resource_dir() const override;  	virtual String get_locale() const override;  	virtual String get_model_name() const override;  	virtual String get_unique_id() const override; -	virtual String get_system_dir(SystemDir p_dir) const override; +	virtual String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const override;  	void vibrate_handheld(int p_duration_ms) override; diff --git a/platform/linuxbsd/os_linuxbsd.cpp b/platform/linuxbsd/os_linuxbsd.cpp index 08630be8b0..2c9801f512 100644 --- a/platform/linuxbsd/os_linuxbsd.cpp +++ b/platform/linuxbsd/os_linuxbsd.cpp @@ -273,7 +273,7 @@ String OS_LinuxBSD::get_cache_path() const {  	}  } -String OS_LinuxBSD::get_system_dir(SystemDir p_dir) const { +String OS_LinuxBSD::get_system_dir(SystemDir p_dir, bool p_shared_storage) const {  	String xdgparam;  	switch (p_dir) { diff --git a/platform/linuxbsd/os_linuxbsd.h b/platform/linuxbsd/os_linuxbsd.h index 1e06587322..35c80e3f9b 100644 --- a/platform/linuxbsd/os_linuxbsd.h +++ b/platform/linuxbsd/os_linuxbsd.h @@ -84,7 +84,7 @@ public:  	virtual String get_data_path() const override;  	virtual String get_cache_path() const override; -	virtual String get_system_dir(SystemDir p_dir) const override; +	virtual String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const override;  	virtual Error shell_open(String p_uri) override; diff --git a/platform/osx/os_osx.h b/platform/osx/os_osx.h index 37d30add78..df41ccd892 100644 --- a/platform/osx/os_osx.h +++ b/platform/osx/os_osx.h @@ -84,7 +84,7 @@ public:  	virtual String get_bundle_resource_dir() const override;  	virtual String get_godot_dir_name() const override; -	virtual String get_system_dir(SystemDir p_dir) const override; +	virtual String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const override;  	Error shell_open(String p_uri) override; diff --git a/platform/osx/os_osx.mm b/platform/osx/os_osx.mm index c458a0264a..c6e35fee83 100644 --- a/platform/osx/os_osx.mm +++ b/platform/osx/os_osx.mm @@ -395,7 +395,7 @@ String OS_OSX::get_godot_dir_name() const {  	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;  	bool found = true; diff --git a/platform/windows/os_windows.cpp b/platform/windows/os_windows.cpp index 2c8afaf7de..2a0a509d43 100644 --- a/platform/windows/os_windows.cpp +++ b/platform/windows/os_windows.cpp @@ -681,7 +681,7 @@ String OS_Windows::get_godot_dir_name() const {  	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;  	switch (p_dir) { diff --git a/platform/windows/os_windows.h b/platform/windows/os_windows.h index ea0c263b78..c4a2eda8f4 100644 --- a/platform/windows/os_windows.h +++ b/platform/windows/os_windows.h @@ -150,7 +150,7 @@ public:  	virtual String get_cache_path() const override;  	virtual String get_godot_dir_name() const override; -	virtual String get_system_dir(SystemDir p_dir) const override; +	virtual String get_system_dir(SystemDir p_dir, bool p_shared_storage = true) const override;  	virtual String get_user_data_dir() const override;  	virtual String get_unique_id() const override;  |