Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.x] Add a method for obtaining display cutouts on Android #60552

Merged
merged 1 commit into from
May 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions core/bind/core_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -355,6 +355,10 @@ Rect2 _OS::get_window_safe_area() const {
return OS::get_singleton()->get_window_safe_area();
}

Array _OS::get_display_cutouts() const {
return OS::get_singleton()->get_display_cutouts();
}

void _OS::set_window_fullscreen(bool p_enabled) {
OS::get_singleton()->set_window_fullscreen(p_enabled);
}
Expand Down Expand Up @@ -1281,6 +1285,7 @@ void _OS::_bind_methods() {
ClassDB::bind_method(D_METHOD("set_min_window_size", "size"), &_OS::set_min_window_size);
ClassDB::bind_method(D_METHOD("set_window_size", "size"), &_OS::set_window_size);
ClassDB::bind_method(D_METHOD("get_window_safe_area"), &_OS::get_window_safe_area);
ClassDB::bind_method(D_METHOD("get_display_cutouts"), &_OS::get_display_cutouts);
ClassDB::bind_method(D_METHOD("set_window_fullscreen", "enabled"), &_OS::set_window_fullscreen);
ClassDB::bind_method(D_METHOD("is_window_fullscreen"), &_OS::is_window_fullscreen);
ClassDB::bind_method(D_METHOD("set_window_resizable", "enabled"), &_OS::set_window_resizable);
Expand Down
1 change: 1 addition & 0 deletions core/bind/core_bind.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ class _OS : public Object {
virtual Size2 get_window_size() const;
virtual Size2 get_real_window_size() const;
virtual Rect2 get_window_safe_area() const;
virtual Array get_display_cutouts() const;
virtual void set_max_window_size(const Size2 &p_size);
virtual void set_min_window_size(const Size2 &p_size);
virtual void set_window_size(const Size2 &p_size);
Expand Down
1 change: 1 addition & 0 deletions core/os/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,7 @@ class OS {
Size2 window_size = get_window_size();
return Rect2(0, 0, window_size.width, window_size.height);
}
virtual Array get_display_cutouts() const { return Array(); }

virtual void set_borderless_window(bool p_borderless) {}
virtual bool get_borderless_window() { return false; }
Expand Down
7 changes: 7 additions & 0 deletions doc/classes/OS.xml
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,13 @@
The returned Dictionary's values will be the same as [method get_datetime], with the exception of Daylight Savings Time as it cannot be determined from the epoch.
</description>
</method>
<method name="get_display_cutouts" qualifiers="const">
<return type="Array" />
<description>
Returns an [Array] of [Rect2], each of which is the bounding rectangle for a display cutout or notch. These are non-functional areas on edge-to-edge screens used by cameras and sensors. Returns an empty array if the device does not have cutouts. See also [method get_window_safe_area].
[b]Note:[/b] Currently only implemented on Android. Other platforms will return an empty array even if they do have display cutouts or notches.
</description>
</method>
<method name="get_dynamic_memory_usage" qualifiers="const">
<return type="int" />
<description>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
import android.content.pm.ActivityInfo;
import android.content.res.AssetManager;
import android.graphics.Point;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
Expand All @@ -51,6 +52,7 @@
import android.view.WindowInsets;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

// Wrapper for native library
Expand Down Expand Up @@ -260,6 +262,25 @@ public int[] getWindowSafeArea() {
return result;
}

public int[] getDisplayCutouts() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P)
return new int[0];
DisplayCutout cutout = activity.getWindow().getDecorView().getRootWindowInsets().getDisplayCutout();
if (cutout == null)
return new int[0];
List<Rect> rects = cutout.getBoundingRects();
int cutouts = rects.size();
int[] result = new int[cutouts * 4];
int index = 0;
for (Rect rect : rects) {
result[index++] = rect.left;
result[index++] = rect.top;
result[index++] = rect.width();
result[index++] = rect.height();
}
return result;
}

public void showKeyboard(String p_existing_text, boolean p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) {
if (edit != null)
edit.showKeyboard(p_existing_text, p_multiline, p_max_input_length, p_cursor_start, p_cursor_end);
Expand Down
25 changes: 25 additions & 0 deletions platform/android/java_godot_io_wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@
/*************************************************************************/

#include "java_godot_io_wrapper.h"
#include "core/array.h"
#include "core/error_list.h"
#include "core/math/rect2.h"
#include "core/variant.h"

// JNIEnv is only valid within the thread it belongs to, in a multi threading environment
// we can't cache it.
Expand All @@ -50,6 +53,7 @@ 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_display_cutouts = p_env->GetMethodID(cls, "getDisplayCutouts", "()[I"),
_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");
Expand Down Expand Up @@ -175,6 +179,27 @@ void GodotIOJavaWrapper::get_window_safe_area(int (&p_rect_xywh)[4]) {
}
}

Array GodotIOJavaWrapper::get_display_cutouts() {
Array result;
ERR_FAIL_NULL_V(_get_display_cutouts, result);
JNIEnv *env = get_jni_env();
ERR_FAIL_NULL_V(env, result);
jintArray returnArray = (jintArray)env->CallObjectMethod(godot_io_instance, _get_display_cutouts);
jint arrayLength = env->GetArrayLength(returnArray);
jint *arrayBody = env->GetIntArrayElements(returnArray, JNI_FALSE);
int cutouts = arrayLength / 4;
for (int i = 0; i < cutouts; i++) {
int x = arrayBody[i * 4];
int y = arrayBody[i * 4 + 1];
int width = arrayBody[i * 4 + 2];
int height = arrayBody[i * 4 + 3];
Rect2 cutout(x, y, width, height);
result.append(cutout);
}
env->ReleaseIntArrayElements(returnArray, arrayBody, 0);
return result;
}

String GodotIOJavaWrapper::get_unique_id() {
if (_get_unique_id) {
JNIEnv *env = get_jni_env();
Expand Down
2 changes: 2 additions & 0 deletions platform/android/java_godot_io_wrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class GodotIOJavaWrapper {
jmethodID _open_URI = 0;
jmethodID _get_cache_dir = 0;
jmethodID _get_data_dir = 0;
jmethodID _get_display_cutouts = 0;
jmethodID _get_locale = 0;
jmethodID _get_model = 0;
jmethodID _get_screen_DPI = 0;
Expand Down Expand Up @@ -75,6 +76,7 @@ class GodotIOJavaWrapper {
int get_screen_dpi();
float get_scaled_density();
void get_window_safe_area(int (&p_rect_xywh)[4]);
Array get_display_cutouts();
float get_screen_refresh_rate(float p_fallback);
String get_unique_id();
bool has_vk();
Expand Down
5 changes: 5 additions & 0 deletions platform/android/os_android.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@

#include "os_android.h"

#include "core/array.h"
#include "core/project_settings.h"
#include "drivers/gles2/rasterizer_gles2.h"
#include "drivers/gles3/rasterizer_gles3.h"
Expand Down Expand Up @@ -302,6 +303,10 @@ Rect2 OS_Android::get_window_safe_area() const {
return Rect2(xywh[0], xywh[1], xywh[2], xywh[3]);
}

Array OS_Android::get_display_cutouts() const {
return godot_io_java->get_display_cutouts();
}

String OS_Android::get_name() const {
return "Android";
}
Expand Down
1 change: 1 addition & 0 deletions platform/android/os_android.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ class OS_Android : public OS_Unix {

virtual Size2 get_window_size() const;
virtual Rect2 get_window_safe_area() const;
virtual Array get_display_cutouts() const;

virtual String get_name() const;
virtual MainLoop *get_main_loop() const;
Expand Down