diff options
Diffstat (limited to 'platform/android/java/lib/src')
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 } |
