summaryrefslogtreecommitdiffstats
path: root/platform/android/java/lib/src
diff options
context:
space:
mode:
Diffstat (limited to 'platform/android/java/lib/src')
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/Godot.java85
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/GodotLib.java7
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt10
-rw-r--r--platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt9
4 files changed, 95 insertions, 16 deletions
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 a03da7292b..e111bd18ca 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java
@@ -74,10 +74,14 @@ import android.util.Log;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.Surface;
+import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
+import android.view.ViewTreeObserver;
import android.view.Window;
+import android.view.WindowInsets;
+import android.view.WindowInsetsAnimation;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.FrameLayout;
@@ -278,7 +282,8 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
if (usesVulkan()) {
if (!meetsVulkanRequirements(activity.getPackageManager())) {
- Log.w(TAG, "Missing requirements for vulkan support!");
+ alert(R.string.error_missing_vulkan_requirements_message, R.string.text_error_title, this::forceQuit);
+ return false;
}
mRenderView = new GodotVulkanRenderView(activity, this);
} else {
@@ -291,14 +296,64 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
editText.setView(mRenderView);
io.setEdit(editText);
- view.getViewTreeObserver().addOnGlobalLayoutListener(() -> {
- Point fullSize = new Point();
- activity.getWindowManager().getDefaultDisplay().getSize(fullSize);
- Rect gameSize = new Rect();
- mRenderView.getView().getWindowVisibleDisplayFrame(gameSize);
- final int keyboardHeight = fullSize.y - gameSize.bottom;
- GodotLib.setVirtualKeyboardHeight(keyboardHeight);
- });
+ // Listeners for keyboard height.
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
+ // Report the height of virtual keyboard as it changes during the animation.
+ final View decorView = activity.getWindow().getDecorView();
+ decorView.setWindowInsetsAnimationCallback(new WindowInsetsAnimation.Callback(WindowInsetsAnimation.Callback.DISPATCH_MODE_STOP) {
+ int startBottom, endBottom;
+ @Override
+ public void onPrepare(@NonNull WindowInsetsAnimation animation) {
+ startBottom = decorView.getRootWindowInsets().getInsets(WindowInsets.Type.ime()).bottom;
+ }
+
+ @NonNull
+ @Override
+ public WindowInsetsAnimation.Bounds onStart(@NonNull WindowInsetsAnimation animation, @NonNull WindowInsetsAnimation.Bounds bounds) {
+ endBottom = decorView.getRootWindowInsets().getInsets(WindowInsets.Type.ime()).bottom;
+ return bounds;
+ }
+
+ @NonNull
+ @Override
+ public WindowInsets onProgress(@NonNull WindowInsets windowInsets, @NonNull List<WindowInsetsAnimation> list) {
+ // Find the IME animation.
+ WindowInsetsAnimation imeAnimation = null;
+ for (WindowInsetsAnimation animation : list) {
+ if ((animation.getTypeMask() & WindowInsets.Type.ime()) != 0) {
+ imeAnimation = animation;
+ break;
+ }
+ }
+ // Update keyboard height based on IME animation.
+ if (imeAnimation != null) {
+ float interpolatedFraction = imeAnimation.getInterpolatedFraction();
+ // Linear interpolation between start and end values.
+ float keyboardHeight = startBottom * (1.0f - interpolatedFraction) + endBottom * interpolatedFraction;
+ GodotLib.setVirtualKeyboardHeight((int)keyboardHeight);
+ }
+ return windowInsets;
+ }
+
+ @Override
+ public void onEnd(@NonNull WindowInsetsAnimation animation) {
+ }
+ });
+ } else {
+ // Infer the virtual keyboard height using visible area.
+ view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
+ // Don't allocate a new Rect every time the callback is called.
+ final Rect visibleSize = new Rect();
+
+ @Override
+ public void onGlobalLayout() {
+ final SurfaceView view = mRenderView.getView();
+ view.getWindowVisibleDisplayFrame(visibleSize);
+ final int keyboardHeight = view.getHeight() - visibleSize.bottom;
+ GodotLib.setVirtualKeyboardHeight(keyboardHeight);
+ }
+ });
+ }
mRenderView.queueOnRenderThread(() -> {
for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
@@ -338,7 +393,17 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
return false;
}
- return Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && packageManager.hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_LEVEL, 1);
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
+ if (!packageManager.hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_LEVEL, 1)) {
+ // Optional requirements.. log as warning if missing
+ Log.w(TAG, "The vulkan hardware level does not meet the minimum requirement: 1");
+ }
+
+ // Check for api version 1.0
+ return packageManager.hasSystemFeature(PackageManager.FEATURE_VULKAN_HARDWARE_VERSION, 0x400003);
+ }
+
+ return false;
}
public void setKeepScreenOn(final boolean p_enabled) {
diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
index 75a01dc787..d9aab950df 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
+++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java
@@ -190,6 +190,13 @@ public class GodotLib {
public static native String getGlobal(String p_key);
/**
+ * Used to access Godot's editor settings.
+ * @param settingKey Setting key
+ * @return String value of the setting
+ */
+ public static native String getEditorSetting(String settingKey);
+
+ /**
* Invoke method |p_method| on the Godot object specified by |p_id|
* @param p_id Id of the Godot object to invoke
* @param p_method Name of the method to invoke
diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt
index 1be009b6dc..af1f38f89c 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.kt
@@ -239,8 +239,8 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi
return true
}
- override fun onScale(detector: ScaleGestureDetector?): Boolean {
- if (detector == null || !panningAndScalingEnabled || pointerCaptureInProgress) {
+ override fun onScale(detector: ScaleGestureDetector): Boolean {
+ if (!panningAndScalingEnabled || pointerCaptureInProgress) {
return false
}
GodotLib.magnify(
@@ -251,15 +251,15 @@ internal class GodotGestureHandler : SimpleOnGestureListener(), OnScaleGestureLi
return true
}
- override fun onScaleBegin(detector: ScaleGestureDetector?): Boolean {
- if (detector == null || !panningAndScalingEnabled || pointerCaptureInProgress) {
+ override fun onScaleBegin(detector: ScaleGestureDetector): Boolean {
+ if (!panningAndScalingEnabled || pointerCaptureInProgress) {
return false
}
scaleInProgress = true
return true
}
- override fun onScaleEnd(detector: ScaleGestureDetector?) {
+ override fun onScaleEnd(detector: ScaleGestureDetector) {
scaleInProgress = false
}
}
diff --git a/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt b/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt
index 833ab40af0..8ee3d5f48f 100644
--- a/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt
+++ b/platform/android/java/lib/src/org/godotengine/godot/io/StorageScope.kt
@@ -76,6 +76,13 @@ internal enum class StorageScope {
return UNKNOWN
}
+ // If we have 'All Files Access' permission, we can access all directories without
+ // restriction.
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R
+ && Environment.isExternalStorageManager()) {
+ return APP
+ }
+
val canonicalPathFile = pathFile.canonicalPath
if (internalAppDir != null && canonicalPathFile.startsWith(internalAppDir)) {
@@ -90,7 +97,7 @@ internal enum class StorageScope {
return APP
}
- var rootDir: String? = System.getenv("ANDROID_ROOT")
+ val rootDir: String? = System.getenv("ANDROID_ROOT")
if (rootDir != null && canonicalPathFile.startsWith(rootDir)) {
return APP
}