diff options
Diffstat (limited to 'platform/android/java/lib')
80 files changed, 598 insertions, 580 deletions
diff --git a/platform/android/java/lib/res/layout/downloading_expansion.xml b/platform/android/java/lib/res/layout/downloading_expansion.xml index 4a9700965f..34c2757598 100644 --- a/platform/android/java/lib/res/layout/downloading_expansion.xml +++ b/platform/android/java/lib/res/layout/downloading_expansion.xml @@ -162,4 +162,4 @@ </LinearLayout> </LinearLayout> -</LinearLayout>
\ No newline at end of file +</LinearLayout> diff --git a/platform/android/java/lib/res/layout/godot_app_layout.xml b/platform/android/java/lib/res/layout/godot_app_layout.xml new file mode 100644 index 0000000000..386ded1c5d --- /dev/null +++ b/platform/android/java/lib/res/layout/godot_app_layout.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/godot_fragment_container" + android:layout_width="match_parent" + android:layout_height="match_parent" /> diff --git a/platform/android/java/lib/res/layout/status_bar_ongoing_event_progress_bar.xml b/platform/android/java/lib/res/layout/status_bar_ongoing_event_progress_bar.xml index fae1faeb60..426e1bd841 100644 --- a/platform/android/java/lib/res/layout/status_bar_ongoing_event_progress_bar.xml +++ b/platform/android/java/lib/res/layout/status_bar_ongoing_event_progress_bar.xml @@ -105,4 +105,4 @@ </RelativeLayout> -</LinearLayout>
\ No newline at end of file +</LinearLayout> diff --git a/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml b/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml index 1ed4037035..cfdcca2ab5 100644 --- a/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml +++ b/platform/android/java/lib/res/mipmap-anydpi-v26/icon.xml @@ -2,4 +2,4 @@ <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <background android:drawable="@mipmap/icon_background"/> <foreground android:drawable="@mipmap/icon_foreground"/> -</adaptive-icon>
\ No newline at end of file +</adaptive-icon> diff --git a/platform/android/java/lib/res/values-ar/strings.xml b/platform/android/java/lib/res/values-ar/strings.xml deleted file mode 100644 index 9f3dc6d6ac..0000000000 --- a/platform/android/java/lib/res/values-ar/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-ar</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-bg/strings.xml b/platform/android/java/lib/res/values-bg/strings.xml deleted file mode 100644 index bd8109277e..0000000000 --- a/platform/android/java/lib/res/values-bg/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-bg</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-ca/strings.xml b/platform/android/java/lib/res/values-ca/strings.xml deleted file mode 100644 index 494cb88468..0000000000 --- a/platform/android/java/lib/res/values-ca/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-ca</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-cs/strings.xml b/platform/android/java/lib/res/values-cs/strings.xml deleted file mode 100644 index 30ce00f895..0000000000 --- a/platform/android/java/lib/res/values-cs/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-cs</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-da/strings.xml b/platform/android/java/lib/res/values-da/strings.xml deleted file mode 100644 index 4c2a1cf0f4..0000000000 --- a/platform/android/java/lib/res/values-da/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-da</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-de/strings.xml b/platform/android/java/lib/res/values-de/strings.xml deleted file mode 100644 index 52946d4cce..0000000000 --- a/platform/android/java/lib/res/values-de/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-de</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-el/strings.xml b/platform/android/java/lib/res/values-el/strings.xml deleted file mode 100644 index 181dc51762..0000000000 --- a/platform/android/java/lib/res/values-el/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-el</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-en/strings.xml b/platform/android/java/lib/res/values-en/strings.xml deleted file mode 100644 index 976a565013..0000000000 --- a/platform/android/java/lib/res/values-en/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-en</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-es-rES/strings.xml b/platform/android/java/lib/res/values-es-rES/strings.xml deleted file mode 100644 index 73f63a08f8..0000000000 --- a/platform/android/java/lib/res/values-es-rES/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-es_ES</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-es/strings.xml b/platform/android/java/lib/res/values-es/strings.xml deleted file mode 100644 index 07b718a641..0000000000 --- a/platform/android/java/lib/res/values-es/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-es</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-fa/strings.xml b/platform/android/java/lib/res/values-fa/strings.xml index f1e29013c4..60b01accf1 100644 --- a/platform/android/java/lib/res/values-fa/strings.xml +++ b/platform/android/java/lib/res/values-fa/strings.xml @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <string name="godot_project_name_string">godot-project-name-fa</string> <string name="text_paused_cellular">آیا می خواهید بر روی اتصال داده همراه دانلود را شروع کنید؟ بر اساس نوع سطح داده شما این ممکن است برای شما هزینه مالی داشته باشد.</string> <string name="text_paused_cellular_2">اگر نمی خواهید بر روی اتصال داده همراه دانلود را شروع کنید ، دانلود به صورت خودکار در زمان دسترسی به وای-فای شروع می شود.</string> <string name="text_button_resume_cellular">ادامه دانلود</string> diff --git a/platform/android/java/lib/res/values-fi/strings.xml b/platform/android/java/lib/res/values-fi/strings.xml deleted file mode 100644 index 323d82aff1..0000000000 --- a/platform/android/java/lib/res/values-fi/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-fi</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-fr/strings.xml b/platform/android/java/lib/res/values-fr/strings.xml deleted file mode 100644 index 32bead2661..0000000000 --- a/platform/android/java/lib/res/values-fr/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-fr</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-hi/strings.xml b/platform/android/java/lib/res/values-hi/strings.xml deleted file mode 100644 index 8aab2a8c63..0000000000 --- a/platform/android/java/lib/res/values-hi/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-hi</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-hr/strings.xml b/platform/android/java/lib/res/values-hr/strings.xml deleted file mode 100644 index caf55e2241..0000000000 --- a/platform/android/java/lib/res/values-hr/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-hr</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-hu/strings.xml b/platform/android/java/lib/res/values-hu/strings.xml deleted file mode 100644 index e7f9e51226..0000000000 --- a/platform/android/java/lib/res/values-hu/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-hu</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-in/strings.xml b/platform/android/java/lib/res/values-in/strings.xml deleted file mode 100644 index 9e9a8b0c03..0000000000 --- a/platform/android/java/lib/res/values-in/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-id</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-it/strings.xml b/platform/android/java/lib/res/values-it/strings.xml deleted file mode 100644 index 1f5e5a049e..0000000000 --- a/platform/android/java/lib/res/values-it/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-it</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-iw/strings.xml b/platform/android/java/lib/res/values-iw/strings.xml deleted file mode 100644 index f52ede2085..0000000000 --- a/platform/android/java/lib/res/values-iw/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-he</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-ja/strings.xml b/platform/android/java/lib/res/values-ja/strings.xml deleted file mode 100644 index 7f85f57df7..0000000000 --- a/platform/android/java/lib/res/values-ja/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-ja</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-ko/strings.xml b/platform/android/java/lib/res/values-ko/strings.xml index fab0bdd753..7b62345977 100644 --- a/platform/android/java/lib/res/values-ko/strings.xml +++ b/platform/android/java/lib/res/values-ko/strings.xml @@ -1,6 +1,5 @@ <?xml version="1.0" encoding="utf-8"?> <resources> - <string name="godot_project_name_string">godot-project-name-ko</string> <string name="text_paused_cellular">모바일 네트워크를 사용하여 다운로드 하시겠습니까? 남은 데이터 사용량에 따라, 요금이 부과될 수 있습니다.</string> <string name="text_paused_cellular_2">모바일 네트워크를 사용하여 다운로드 하지 않을 경우, 와이파이 연결이 가능할 때 자동적으로 다운로드가 이루어집니다.</string> <string name="text_button_resume_cellular">다운로드 계속하기</string> @@ -52,4 +51,4 @@ <string name="kilobytes_per_second">%1$s KB/s</string> <string name="time_remaining">남은 시간: %1$s</string> <string name="time_remaining_notification">%1$s 남음</string> -</resources>
\ No newline at end of file +</resources> diff --git a/platform/android/java/lib/res/values-lt/strings.xml b/platform/android/java/lib/res/values-lt/strings.xml deleted file mode 100644 index 6e3677fde7..0000000000 --- a/platform/android/java/lib/res/values-lt/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-lt</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-lv/strings.xml b/platform/android/java/lib/res/values-lv/strings.xml deleted file mode 100644 index 701fc271ac..0000000000 --- a/platform/android/java/lib/res/values-lv/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-lv</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-nb/strings.xml b/platform/android/java/lib/res/values-nb/strings.xml deleted file mode 100644 index 73147ca1af..0000000000 --- a/platform/android/java/lib/res/values-nb/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-nb</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-nl/strings.xml b/platform/android/java/lib/res/values-nl/strings.xml deleted file mode 100644 index e501928a35..0000000000 --- a/platform/android/java/lib/res/values-nl/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-nl</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-pl/strings.xml b/platform/android/java/lib/res/values-pl/strings.xml deleted file mode 100644 index ea5da73b6f..0000000000 --- a/platform/android/java/lib/res/values-pl/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-pl</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-pt/strings.xml b/platform/android/java/lib/res/values-pt/strings.xml deleted file mode 100644 index bdda7cd2c7..0000000000 --- a/platform/android/java/lib/res/values-pt/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-pt</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-ro/strings.xml b/platform/android/java/lib/res/values-ro/strings.xml deleted file mode 100644 index 3686da4c19..0000000000 --- a/platform/android/java/lib/res/values-ro/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-ro</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-ru/strings.xml b/platform/android/java/lib/res/values-ru/strings.xml deleted file mode 100644 index 954067658b..0000000000 --- a/platform/android/java/lib/res/values-ru/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-ru</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-sk/strings.xml b/platform/android/java/lib/res/values-sk/strings.xml deleted file mode 100644 index 37d1283124..0000000000 --- a/platform/android/java/lib/res/values-sk/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-sk</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-sl/strings.xml b/platform/android/java/lib/res/values-sl/strings.xml deleted file mode 100644 index 0bb249c375..0000000000 --- a/platform/android/java/lib/res/values-sl/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-sl</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-sr/strings.xml b/platform/android/java/lib/res/values-sr/strings.xml deleted file mode 100644 index 0e83cab1a1..0000000000 --- a/platform/android/java/lib/res/values-sr/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-sr</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-sv/strings.xml b/platform/android/java/lib/res/values-sv/strings.xml deleted file mode 100644 index e3a04ac2ec..0000000000 --- a/platform/android/java/lib/res/values-sv/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-sv</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-th/strings.xml b/platform/android/java/lib/res/values-th/strings.xml deleted file mode 100644 index 0aa893b8bf..0000000000 --- a/platform/android/java/lib/res/values-th/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-th</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-tl/strings.xml b/platform/android/java/lib/res/values-tl/strings.xml deleted file mode 100644 index e7e2af4909..0000000000 --- a/platform/android/java/lib/res/values-tl/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-tl</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-tr/strings.xml b/platform/android/java/lib/res/values-tr/strings.xml deleted file mode 100644 index 97af1243a6..0000000000 --- a/platform/android/java/lib/res/values-tr/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-tr</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-uk/strings.xml b/platform/android/java/lib/res/values-uk/strings.xml deleted file mode 100644 index 3dea6908a9..0000000000 --- a/platform/android/java/lib/res/values-uk/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-uk</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-vi/strings.xml b/platform/android/java/lib/res/values-vi/strings.xml deleted file mode 100644 index a6552130b0..0000000000 --- a/platform/android/java/lib/res/values-vi/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-vi</string> -</resources>
\ No newline at end of file diff --git a/platform/android/java/lib/res/values-zh-rCN/strings.xml b/platform/android/java/lib/res/values-zh-rCN/strings.xml deleted file mode 100644 index 6668c56bd9..0000000000 --- a/platform/android/java/lib/res/values-zh-rCN/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-zh</string> -</resources> diff --git a/platform/android/java/lib/res/values-zh-rHK/strings.xml b/platform/android/java/lib/res/values-zh-rHK/strings.xml deleted file mode 100644 index 8a6269da0f..0000000000 --- a/platform/android/java/lib/res/values-zh-rHK/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-zh_HK</string> -</resources> diff --git a/platform/android/java/lib/res/values-zh-rTW/strings.xml b/platform/android/java/lib/res/values-zh-rTW/strings.xml deleted file mode 100644 index b1bb39d5d6..0000000000 --- a/platform/android/java/lib/res/values-zh-rTW/strings.xml +++ /dev/null @@ -1,4 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<resources> - <string name="godot_project_name_string">godot-project-name-zh_TW</string> -</resources> diff --git a/platform/android/java/lib/res/values/strings.xml b/platform/android/java/lib/res/values/strings.xml index a1b81a6186..590b066d8a 100644 --- a/platform/android/java/lib/res/values/strings.xml +++ b/platform/android/java/lib/res/values/strings.xml @@ -52,4 +52,4 @@ <string name="kilobytes_per_second">%1$s KB/s</string> <string name="time_remaining">Time remaining: %1$s</string> <string name="time_remaining_notification">%1$s left</string> -</resources>
\ No newline at end of file +</resources> diff --git a/platform/android/java/lib/res/values/styles.xml b/platform/android/java/lib/res/values/styles.xml index a442f61e7e..b798373bc6 100644 --- a/platform/android/java/lib/res/values/styles.xml +++ b/platform/android/java/lib/res/values/styles.xml @@ -22,4 +22,4 @@ <item name="android:background">@android:color/background_dark</item> </style> -</resources>
\ No newline at end of file +</resources> diff --git a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java index 0abaf2e052..d481c22204 100644 --- a/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java +++ b/platform/android/java/lib/src/com/google/android/vending/expansion/downloader/impl/DownloadNotification.java @@ -29,9 +29,9 @@ import com.google.android.vending.expansion.downloader.IDownloaderClient; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; -import android.os.Build; import android.os.Messenger; -import android.support.v4.app.NotificationCompat; + +import androidx.core.app.NotificationCompat; /** * This class handles displaying the notification associated with the download diff --git a/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java b/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java index 594cae774b..8b7a9c6c74 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Dictionary.java @@ -34,16 +34,13 @@ import java.util.HashMap; import java.util.Set; public class Dictionary extends HashMap<String, Object> { - protected String[] keys_cache; public String[] get_keys() { - String[] ret = new String[size()]; int i = 0; Set<String> keys = keySet(); for (String key : keys) { - ret[i] = key; i++; }; @@ -52,12 +49,10 @@ public class Dictionary extends HashMap<String, Object> { }; public Object[] get_values() { - Object[] ret = new Object[size()]; int i = 0; Set<String> keys = keySet(); for (String key : keys) { - ret[i] = get(key); i++; }; @@ -70,7 +65,6 @@ public class Dictionary extends HashMap<String, Object> { }; public void set_values(Object[] vals) { - int i = 0; for (String key : keys_cache) { put(key, vals[i]); diff --git a/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java new file mode 100644 index 0000000000..138c2de94c --- /dev/null +++ b/platform/android/java/lib/src/org/godotengine/godot/FullScreenGodotApp.java @@ -0,0 +1,79 @@ +/*************************************************************************/ +/* FullScreenGodotApp.java */ +/*************************************************************************/ +/* This file is part of: */ +/* GODOT ENGINE */ +/* https://godotengine.org */ +/*************************************************************************/ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ +/* */ +/* Permission is hereby granted, free of charge, to any person obtaining */ +/* a copy of this software and associated documentation files (the */ +/* "Software"), to deal in the Software without restriction, including */ +/* without limitation the rights to use, copy, modify, merge, publish, */ +/* distribute, sublicense, and/or sell copies of the Software, and to */ +/* permit persons to whom the Software is furnished to do so, subject to */ +/* the following conditions: */ +/* */ +/* The above copyright notice and this permission notice shall be */ +/* included in all copies or substantial portions of the Software. */ +/* */ +/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ +/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ +/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ +/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ +/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ +/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ +/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ +/*************************************************************************/ + +package org.godotengine.godot; + +import android.content.Intent; +import android.os.Bundle; +import android.view.KeyEvent; + +import androidx.fragment.app.FragmentActivity; + +/** + * Base activity for Android apps intending to use Godot as the primary and only screen. + * + * It's also a reference implementation for how to setup and use the {@link Godot} fragment + * within an Android app. + */ +public abstract class FullScreenGodotApp extends FragmentActivity { + protected Godot godotFragment; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.godot_app_layout); + godotFragment = new Godot(); + getSupportFragmentManager().beginTransaction().replace(R.id.godot_fragment_container, godotFragment).setPrimaryNavigationFragment(godotFragment).commitNowAllowingStateLoss(); + } + + @Override + public void onNewIntent(Intent intent) { + if (godotFragment != null) { + godotFragment.onNewIntent(intent); + } + } + + @Override + public void onBackPressed() { + if (godotFragment != null) { + godotFragment.onBackPressed(); + } else { + super.onBackPressed(); + } + } + + @Override + public boolean onKeyMultiple(final int inKeyCode, int repeatCount, KeyEvent event) { + if (godotFragment != null && godotFragment.onKeyMultiple(inKeyCode, repeatCount, event)) { + return true; + } + return super.onKeyMultiple(inKeyCode, repeatCount, event); + } +} 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 bf0d1c6273..35852f31ef 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/Godot.java +++ b/platform/android/java/lib/src/org/godotengine/godot/Godot.java @@ -30,6 +30,16 @@ package org.godotengine.godot; +import static android.content.Context.MODE_PRIVATE; +import static android.content.Context.WINDOW_SERVICE; + +import org.godotengine.godot.input.GodotEditText; +import org.godotengine.godot.plugin.GodotPlugin; +import org.godotengine.godot.plugin.GodotPluginRegistry; +import org.godotengine.godot.utils.GodotNetUtils; +import org.godotengine.godot.utils.PermissionsUtil; +import org.godotengine.godot.xr.XRMode; + import android.annotation.SuppressLint; import android.app.Activity; import android.app.ActivityManager; @@ -46,8 +56,6 @@ import android.content.SharedPreferences.Editor; import android.content.pm.ConfigurationInfo; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; -import android.graphics.Point; -import android.graphics.Rect; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; @@ -59,24 +67,26 @@ import android.os.Messenger; import android.os.VibrationEffect; import android.os.Vibrator; import android.provider.Settings.Secure; -import android.support.annotation.CallSuper; -import android.support.annotation.Keep; -import android.support.annotation.NonNull; -import android.support.v4.app.FragmentActivity; import android.view.Display; import android.view.KeyEvent; +import android.view.LayoutInflater; import android.view.MotionEvent; 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; import android.widget.FrameLayout; import android.widget.ProgressBar; import android.widget.TextView; + +import androidx.annotation.CallSuper; +import androidx.annotation.Keep; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + import com.google.android.vending.expansion.downloader.DownloadProgressInfo; import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller; import com.google.android.vending.expansion.downloader.DownloaderServiceMarshaller; @@ -84,6 +94,7 @@ import com.google.android.vending.expansion.downloader.Helpers; import com.google.android.vending.expansion.downloader.IDownloaderClient; import com.google.android.vending.expansion.downloader.IDownloaderService; import com.google.android.vending.expansion.downloader.IStub; + import java.io.File; import java.io.FileInputStream; import java.io.InputStream; @@ -91,15 +102,8 @@ import java.security.MessageDigest; import java.util.LinkedList; import java.util.List; import java.util.Locale; -import org.godotengine.godot.input.GodotEditText; -import org.godotengine.godot.plugin.GodotPlugin; -import org.godotengine.godot.plugin.GodotPluginRegistry; -import org.godotengine.godot.utils.GodotNetUtils; -import org.godotengine.godot.utils.PermissionsUtil; -import org.godotengine.godot.xr.XRMode; - -public abstract class Godot extends FragmentActivity implements SensorEventListener, IDownloaderClient { +public class Godot extends Fragment implements SensorEventListener, IDownloaderClient { private IStub mDownloaderClientStub; private TextView mStatusText; private TextView mProgressFraction; @@ -127,7 +131,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe static private Intent mCurrentIntent; - @Override public void onNewIntent(Intent intent) { mCurrentIntent = intent; } @@ -153,9 +156,12 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe private String[] command_line; private boolean use_apk_expansion; + private ViewGroup containerLayout; public GodotRenderView mRenderView; private boolean godot_initialized = false; + private GodotEditText mEditText; + private SensorManager mSensorManager; private Sensor mAccelerometer; private Sensor mGravity; @@ -171,7 +177,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe public ResultCallback result_callback; @Override - protected void onActivityResult(int requestCode, int resultCode, Intent data) { + public void onActivityResult(int requestCode, int resultCode, Intent data) { if (result_callback != null) { result_callback.callback(requestCode, resultCode, data); result_callback = null; @@ -208,47 +214,29 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe */ @Keep private void onVideoInit() { - final FrameLayout layout = new FrameLayout(this); - layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); - setContentView(layout); - - // GodotEditText layout - GodotEditText editText = new GodotEditText(this); - editText.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); - // ...add to FrameLayout - layout.addView(editText); + final Activity activity = getActivity(); + containerLayout = new FrameLayout(activity); + containerLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); GodotLib.setup(command_line); final String videoDriver = GodotLib.getGlobal("rendering/quality/driver/driver_name"); if (videoDriver.equals("Vulkan")) { - mRenderView = new GodotVulkanRenderView(this); + mRenderView = new GodotVulkanRenderView(activity, this); } else { - mRenderView = new GodotGLRenderView(this, xrMode, use_32_bits, use_debug_opengl); + mRenderView = new GodotGLRenderView(activity, this, xrMode, use_32_bits, + use_debug_opengl); } View view = mRenderView.getView(); - layout.addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); - editText.setView(mRenderView); - io.setEdit(editText); + containerLayout.addView(view, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); - view.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { - @Override - public void onGlobalLayout() { - Point fullSize = new Point(); - getWindowManager().getDefaultDisplay().getSize(fullSize); - Rect gameSize = new Rect(); - mRenderView.getView().getWindowVisibleDisplayFrame(gameSize); - - final int keyboardHeight = fullSize.y - gameSize.bottom; - GodotLib.setVirtualKeyboardHeight(keyboardHeight); - } - }); + mEditText = new GodotEditText(activity, mRenderView); + io.setEdit(mEditText); mRenderView.queueOnRenderThread(new Runnable() { @Override public void run() { - // Must occur after GodotLib.setup has completed. for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) { plugin.onRegisterPluginWithGodotNative(); @@ -260,9 +248,9 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe // Include the returned non-null views in the Godot view hierarchy. for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) { - View pluginView = plugin.onMainCreateView(this); + View pluginView = plugin.onMainCreate(activity); if (pluginView != null) { - layout.addView(pluginView); + containerLayout.addView(pluginView); } } } @@ -272,9 +260,9 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe @Override public void run() { if (p_enabled) { - getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } else { - getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); + getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } } }); @@ -288,7 +276,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe @Keep private void vibrate(int durationMs) { if (requestPermission("VIBRATE")) { - Vibrator v = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE); + Vibrator v = (Vibrator)getContext().getSystemService(Context.VIBRATOR_SERVICE); if (v != null) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { v.vibrate(VibrationEffect.createOneShot(durationMs, VibrationEffect.DEFAULT_AMPLITUDE)); @@ -312,13 +300,16 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe // Using instrumentation is a way of making the whole app process restart, because Android // will kill any process of the same package which was already running. // - Bundle args = new Bundle(); - args.putParcelable("intent", mCurrentIntent); - startInstrumentation(new ComponentName(this, GodotInstrumentation.class), null, args); + final Activity activity = getActivity(); + if (activity != null) { + Bundle args = new Bundle(); + args.putParcelable("intent", mCurrentIntent); + activity.startInstrumentation(new ComponentName(activity, GodotInstrumentation.class), null, args); + } } public void alert(final String message, final String title) { - final Activity activity = this; + final Activity activity = getActivity(); runOnUiThread(new Runnable() { @Override public void run() { @@ -338,15 +329,16 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe } public int getGLESVersionCode() { - ActivityManager am = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE); + ActivityManager am = (ActivityManager)getContext().getSystemService(Context.ACTIVITY_SERVICE); ConfigurationInfo deviceInfo = am.getDeviceConfigurationInfo(); return deviceInfo.reqGlEsVersion; } - private String[] getCommandLine() { + @CallSuper + protected String[] getCommandLine() { InputStream is; try { - is = getAssets().open("_cl_"); + is = getActivity().getAssets().open("_cl_"); byte[] len = new byte[4]; int r = is.read(len); if (r < 4) { @@ -358,7 +350,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe for (int i = 0; i < argc; i++) { r = is.read(len); if (r < 4) { - return new String[0]; } int strlen = ((int)(len[3] & 0xFF) << 24) | ((int)(len[2] & 0xFF) << 16) | ((int)(len[1] & 0xFF) << 8) | ((int)(len[0] & 0xFF)); @@ -406,9 +397,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe String expansion_pack_path; private void initializeGodot() { - if (expansion_pack_path != null) { - String[] new_cmdline; int cll = 0; if (command_line != null) { @@ -426,11 +415,12 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe command_line = new_cmdline; } - io = new GodotIO(this); - io.unique_id = Secure.getString(getContentResolver(), Secure.ANDROID_ID); + final Activity activity = getActivity(); + io = new GodotIO(activity); + io.unique_id = Secure.getString(activity.getContentResolver(), Secure.ANDROID_ID); GodotLib.io = io; - netUtils = new GodotNetUtils(this); - mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); + netUtils = new GodotNetUtils(activity); + mSensorManager = (SensorManager)activity.getSystemService(Context.SENSOR_SERVICE); mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME); mGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY); @@ -440,7 +430,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE); mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME); - GodotLib.initialize(this, getAssets(), use_apk_expansion); + GodotLib.initialize(activity, this, activity.getAssets(), use_apk_expansion); result_callback = null; @@ -454,157 +444,167 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe } @Override - protected void onCreate(Bundle icicle) { - - super.onCreate(icicle); - Window window = getWindow(); + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle) { + final Activity activity = getActivity(); + Window window = activity.getWindow(); window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); - mClipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE); + window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING); + mClipboard = (ClipboardManager)activity.getSystemService(Context.CLIPBOARD_SERVICE); pluginRegistry = GodotPluginRegistry.initializePluginRegistry(this); //check for apk expansion API - if (true) { - boolean md5mismatch = false; - command_line = getCommandLine(); - String main_pack_md5 = null; - String main_pack_key = null; - - List<String> new_args = new LinkedList<String>(); - - for (int i = 0; i < command_line.length; i++) { - - boolean has_extra = i < command_line.length - 1; - if (command_line[i].equals(XRMode.REGULAR.cmdLineArg)) { - xrMode = XRMode.REGULAR; - } else if (command_line[i].equals(XRMode.OVR.cmdLineArg)) { - xrMode = XRMode.OVR; - } else if (command_line[i].equals("--use_depth_32")) { - use_32_bits = true; - } else if (command_line[i].equals("--debug_opengl")) { - use_debug_opengl = true; - } else if (command_line[i].equals("--use_immersive")) { - use_immersive = true; - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // check if the application runs on an android 4.4+ - window.getDecorView().setSystemUiVisibility( - View.SYSTEM_UI_FLAG_LAYOUT_STABLE | - View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | - View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | - View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | // hide nav bar - View.SYSTEM_UI_FLAG_FULLSCREEN | // hide status bar - View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); - - UiChangeListener(); - } - } else if (command_line[i].equals("--use_apk_expansion")) { - use_apk_expansion = true; - } else if (has_extra && command_line[i].equals("--apk_expansion_md5")) { - main_pack_md5 = command_line[i + 1]; - i++; - } else if (has_extra && command_line[i].equals("--apk_expansion_key")) { - main_pack_key = command_line[i + 1]; - SharedPreferences prefs = getSharedPreferences("app_data_keys", MODE_PRIVATE); - Editor editor = prefs.edit(); - editor.putString("store_public_key", main_pack_key); - - editor.apply(); - i++; - } else if (command_line[i].trim().length() != 0) { - new_args.add(command_line[i]); + boolean md5mismatch = false; + command_line = getCommandLine(); + String main_pack_md5 = null; + String main_pack_key = null; + + List<String> new_args = new LinkedList<String>(); + + for (int i = 0; i < command_line.length; i++) { + boolean has_extra = i < command_line.length - 1; + if (command_line[i].equals(XRMode.REGULAR.cmdLineArg)) { + xrMode = XRMode.REGULAR; + } else if (command_line[i].equals(XRMode.OVR.cmdLineArg)) { + xrMode = XRMode.OVR; + } else if (command_line[i].equals("--use_depth_32")) { + use_32_bits = true; + } else if (command_line[i].equals("--debug_opengl")) { + use_debug_opengl = true; + } else if (command_line[i].equals("--use_immersive")) { + use_immersive = true; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // check if the application runs on an android 4.4+ + window.getDecorView().setSystemUiVisibility( + View.SYSTEM_UI_FLAG_LAYOUT_STABLE | + View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | + View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN | + View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | // hide nav bar + View.SYSTEM_UI_FLAG_FULLSCREEN | // hide status bar + View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY); + + UiChangeListener(); } + } else if (command_line[i].equals("--use_apk_expansion")) { + use_apk_expansion = true; + } else if (has_extra && command_line[i].equals("--apk_expansion_md5")) { + main_pack_md5 = command_line[i + 1]; + i++; + } else if (has_extra && command_line[i].equals("--apk_expansion_key")) { + main_pack_key = command_line[i + 1]; + SharedPreferences prefs = activity.getSharedPreferences("app_data_keys", + MODE_PRIVATE); + Editor editor = prefs.edit(); + editor.putString("store_public_key", main_pack_key); + + editor.apply(); + i++; + } else if (command_line[i].trim().length() != 0) { + new_args.add(command_line[i]); } + } - if (new_args.isEmpty()) { - command_line = null; - } else { - - command_line = new_args.toArray(new String[new_args.size()]); + if (new_args.isEmpty()) { + command_line = null; + } else { + command_line = new_args.toArray(new String[new_args.size()]); + } + if (use_apk_expansion && main_pack_md5 != null && main_pack_key != null) { + //check that environment is ok! + if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { + //show popup and die } - if (use_apk_expansion && main_pack_md5 != null && main_pack_key != null) { - //check that environment is ok! - if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { - //show popup and die - } - // Build the full path to the app's expansion files - try { - expansion_pack_path = Helpers.getSaveFilePath(getApplicationContext()); - expansion_pack_path += "/main." + getPackageManager().getPackageInfo(getPackageName(), 0).versionCode + "." + this.getPackageName() + ".obb"; - } catch (Exception e) { - e.printStackTrace(); - } - - File f = new File(expansion_pack_path); + // Build the full path to the app's expansion files + try { + expansion_pack_path = Helpers.getSaveFilePath(getContext()); + expansion_pack_path += "/main." + activity.getPackageManager().getPackageInfo(activity.getPackageName(), 0).versionCode + "." + activity.getPackageName() + ".obb"; + } catch (Exception e) { + e.printStackTrace(); + } - boolean pack_valid = true; + File f = new File(expansion_pack_path); - if (!f.exists()) { + boolean pack_valid = true; - pack_valid = false; + if (!f.exists()) { + pack_valid = false; - } else if (obbIsCorrupted(expansion_pack_path, main_pack_md5)) { - pack_valid = false; - try { - f.delete(); - } catch (Exception e) { - } + } else if (obbIsCorrupted(expansion_pack_path, main_pack_md5)) { + pack_valid = false; + try { + f.delete(); + } catch (Exception e) { } + } - if (!pack_valid) { - - Intent notifierIntent = new Intent(this, this.getClass()); - notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | - Intent.FLAG_ACTIVITY_CLEAR_TOP); + if (!pack_valid) { + Intent notifierIntent = new Intent(activity, activity.getClass()); + notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | + Intent.FLAG_ACTIVITY_CLEAR_TOP); - PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, - notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT); + PendingIntent pendingIntent = PendingIntent.getActivity(activity, 0, + notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT); - int startResult; - try { - startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired( - getApplicationContext(), - pendingIntent, + int startResult; + try { + startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired( + getContext(), + pendingIntent, + GodotDownloaderService.class); + + if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) { + // This is where you do set up to display the download + // progress (next step) + mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this, GodotDownloaderService.class); - if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) { - // This is where you do set up to display the download - // progress (next step) - mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this, - GodotDownloaderService.class); - - setContentView(R.layout.downloading_expansion); - mPB = (ProgressBar)findViewById(R.id.progressBar); - mStatusText = (TextView)findViewById(R.id.statusText); - mProgressFraction = (TextView)findViewById(R.id.progressAsFraction); - mProgressPercent = (TextView)findViewById(R.id.progressAsPercentage); - mAverageSpeed = (TextView)findViewById(R.id.progressAverageSpeed); - mTimeRemaining = (TextView)findViewById(R.id.progressTimeRemaining); - mDashboard = findViewById(R.id.downloaderDashboard); - mCellMessage = findViewById(R.id.approveCellular); - mPauseButton = (Button)findViewById(R.id.pauseButton); - mWiFiSettingsButton = (Button)findViewById(R.id.wifiSettingsButton); - - return; - } - } catch (NameNotFoundException e) { - // TODO Auto-generated catch block + View downloadingExpansionView = + inflater.inflate(R.layout.downloading_expansion, container, false); + mPB = (ProgressBar)downloadingExpansionView.findViewById(R.id.progressBar); + mStatusText = (TextView)downloadingExpansionView.findViewById(R.id.statusText); + mProgressFraction = (TextView)downloadingExpansionView.findViewById(R.id.progressAsFraction); + mProgressPercent = (TextView)downloadingExpansionView.findViewById(R.id.progressAsPercentage); + mAverageSpeed = (TextView)downloadingExpansionView.findViewById(R.id.progressAverageSpeed); + mTimeRemaining = (TextView)downloadingExpansionView.findViewById(R.id.progressTimeRemaining); + mDashboard = downloadingExpansionView.findViewById(R.id.downloaderDashboard); + mCellMessage = downloadingExpansionView.findViewById(R.id.approveCellular); + mPauseButton = (Button)downloadingExpansionView.findViewById(R.id.pauseButton); + mWiFiSettingsButton = (Button)downloadingExpansionView.findViewById(R.id.wifiSettingsButton); + + return downloadingExpansionView; } + } catch (NameNotFoundException e) { + // TODO Auto-generated catch block } } } - mCurrentIntent = getIntent(); + mCurrentIntent = activity.getIntent(); initializeGodot(); + return containerLayout; } @Override - protected void onDestroy() { + public void onStart() { + super.onStart(); + + mRenderView.getView().post(new Runnable() { + @Override + public void run() { + mEditText.onInitView(); + } + }); + } + + @Override + public void onDestroy() { + mEditText.onDestroyView(); for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) { plugin.onMainDestroy(); } - GodotLib.ondestroy(this); + GodotLib.ondestroy(); super.onDestroy(); @@ -614,13 +614,13 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe } @Override - protected void onPause() { + public void onPause() { super.onPause(); activityResumed = false; if (!godot_initialized) { if (null != mDownloaderClientStub) { - mDownloaderClientStub.disconnect(this); + mDownloaderClientStub.disconnect(getActivity()); } return; } @@ -634,7 +634,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe } public String getClipboard() { - String copiedText = ""; if (mClipboard.getPrimaryClip() != null) { @@ -646,18 +645,17 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe } public void setClipboard(String p_text) { - ClipData clip = ClipData.newPlainText("myLabel", p_text); mClipboard.setPrimaryClip(clip); } @Override - protected void onResume() { + public void onResume() { super.onResume(); activityResumed = true; if (!godot_initialized) { if (null != mDownloaderClientStub) { - mDownloaderClientStub.connect(this); + mDownloaderClientStub.connect(getActivity()); } return; } @@ -670,7 +668,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME); if (use_immersive && Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { // check if the application runs on an android 4.4+ - Window window = getWindow(); + Window window = getActivity().getWindow(); window.getDecorView().setSystemUiVisibility( View.SYSTEM_UI_FLAG_LAYOUT_STABLE | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | @@ -686,7 +684,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe } public void UiChangeListener() { - final View decorView = getWindow().getDecorView(); + final View decorView = getActivity().getWindow().getDecorView(); decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() { @Override public void onSystemUiVisibilityChange(int visibility) { @@ -707,7 +705,8 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe @Override public void onSensorChanged(SensorEvent event) { - Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); + Display display = + ((WindowManager)getActivity().getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); int displayRotation = display.getRotation(); float[] adjustedValues = new float[3]; @@ -770,7 +769,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe } */ - @Override public void onBackPressed() { boolean shouldQuit = true; @@ -801,14 +799,18 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe } } + public final void runOnUiThread(@NonNull Runnable action) { + if (getActivity() != null) { + getActivity().runOnUiThread(action); + } + } + private void forceQuit() { System.exit(0); } private boolean obbIsCorrupted(String f, String main_pack_md5) { - try { - InputStream fis = new FileInputStream(f); // Create MD5 Hash @@ -849,7 +851,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe } public boolean gotTouchEvent(final MotionEvent event) { - final int evcount = event.getPointerCount(); if (evcount == 0) return true; @@ -858,7 +859,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe final int[] arr = new int[event.getPointerCount() * 3]; for (int i = 0; i < event.getPointerCount(); i++) { - arr[i * 3 + 0] = (int)event.getPointerId(i); arr[i * 3 + 1] = (int)event.getX(i); arr[i * 3 + 2] = (int)event.getY(i); @@ -907,17 +907,17 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe return true; } - @Override public boolean onKeyMultiple(final int inKeyCode, int repeatCount, KeyEvent event) { String s = event.getCharacters(); if (s == null || s.length() == 0) - return super.onKeyMultiple(inKeyCode, repeatCount, event); + return false; final char[] cc = s.toCharArray(); int cnt = 0; for (int i = cc.length; --i >= 0; cnt += cc[i] != 0 ? 1 : 0) ; - if (cnt == 0) return super.onKeyMultiple(inKeyCode, repeatCount, event); + if (cnt == 0) + return false; mRenderView.queueOnRenderThread(new Runnable() { // This method will be called on the rendering thread: public void run() { @@ -935,15 +935,15 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe } public boolean requestPermission(String p_name) { - return PermissionsUtil.requestPermission(p_name, this); + return PermissionsUtil.requestPermission(p_name, getActivity()); } public boolean requestPermissions() { - return PermissionsUtil.requestManifestPermissions(this); + return PermissionsUtil.requestManifestPermissions(getActivity()); } public String[] getGrantedPermissions() { - return PermissionsUtil.getGrantedPermissions(this); + return PermissionsUtil.getGrantedPermissions(getActivity()); } /** diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java index 1fb242d0bc..a3dae15980 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderAlarmReceiver.java @@ -35,6 +35,7 @@ import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager.NameNotFoundException; import android.util.Log; + import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller; /** @@ -45,7 +46,6 @@ import com.google.android.vending.expansion.downloader.DownloaderClientMarshalle * <receiver android:name=".GodotDownloaderAlarmReceiver"/> */ public class GodotDownloaderAlarmReceiver extends BroadcastReceiver { - @Override public void onReceive(Context context, Intent intent) { Log.d("GODOT", "Alarma recivida"); diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java index 7e74e8a80d..434da95bc0 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotDownloaderService.java @@ -33,6 +33,7 @@ package org.godotengine.godot; import android.content.Context; import android.content.SharedPreferences; import android.util.Log; + import com.google.android.vending.expansion.downloader.impl.DownloaderService; /** diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java index 9be93243b8..d169f46599 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotGLRenderView.java @@ -29,13 +29,7 @@ /*************************************************************************/ package org.godotengine.godot; -import android.annotation.SuppressLint; -import android.graphics.PixelFormat; -import android.opengl.GLSurfaceView; -import android.view.GestureDetector; -import android.view.KeyEvent; -import android.view.MotionEvent; -import android.view.SurfaceView; + import org.godotengine.godot.input.GodotGestureHandler; import org.godotengine.godot.input.GodotInputHandler; import org.godotengine.godot.utils.GLUtils; @@ -47,6 +41,15 @@ import org.godotengine.godot.xr.regular.RegularConfigChooser; import org.godotengine.godot.xr.regular.RegularContextFactory; import org.godotengine.godot.xr.regular.RegularFallbackConfigChooser; +import android.annotation.SuppressLint; +import android.content.Context; +import android.graphics.PixelFormat; +import android.opengl.GLSurfaceView; +import android.view.GestureDetector; +import android.view.KeyEvent; +import android.view.MotionEvent; +import android.view.SurfaceView; + /** * A simple GLSurfaceView sub-class that demonstrate how to perform * OpenGL ES 2.0 rendering into a GL Surface. Note the following important @@ -66,20 +69,20 @@ import org.godotengine.godot.xr.regular.RegularFallbackConfigChooser; * bit depths). Failure to do so would result in an EGL_BAD_MATCH error. */ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView { - - private final Godot activity; + private final Godot godot; private final GodotInputHandler inputHandler; private final GestureDetector detector; private final GodotRenderer godotRenderer; - public GodotGLRenderView(Godot activity, XRMode xrMode, boolean p_use_32_bits, boolean p_use_debug_opengl) { - super(activity); + public GodotGLRenderView(Context context, Godot godot, XRMode xrMode, boolean p_use_32_bits, + boolean p_use_debug_opengl) { + super(context); GLUtils.use_32 = p_use_32_bits; GLUtils.use_debug_opengl = p_use_debug_opengl; - this.activity = activity; + this.godot = godot; this.inputHandler = new GodotInputHandler(this); - this.detector = new GestureDetector(activity, new GodotGestureHandler(this)); + this.detector = new GestureDetector(context, new GodotGestureHandler(this)); this.godotRenderer = new GodotRenderer(); init(xrMode, false, 16, 0); } @@ -111,7 +114,12 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView @Override public void onBackPressed() { - activity.onBackPressed(); + godot.onBackPressed(); + } + + @Override + public GodotInputHandler getInputHandler() { + return inputHandler; } @SuppressLint("ClickableViewAccessibility") @@ -119,7 +127,7 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); this.detector.onTouchEvent(event); - return activity.gotTouchEvent(event); + return godot.gotTouchEvent(event); } @Override @@ -138,11 +146,9 @@ public class GodotGLRenderView extends GLSurfaceView implements GodotRenderView } private void init(XRMode xrMode, boolean translucent, int depth, int stencil) { - setPreserveEGLContextOnPause(true); setFocusableInTouchMode(true); switch (xrMode) { - case OVR: // Replace the default egl config chooser. setEGLConfigChooser(new OvrConfigChooser()); 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 016a3a8d18..c2f3c88416 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotIO.java @@ -29,6 +29,10 @@ /*************************************************************************/ package org.godotengine.godot; + +import org.godotengine.godot.input.*; + +import android.app.Activity; import android.content.*; import android.content.Intent; import android.content.pm.ActivityInfo; @@ -39,18 +43,16 @@ import android.os.*; import android.util.DisplayMetrics; import android.util.Log; import android.util.SparseArray; + import java.io.IOException; import java.io.InputStream; import java.util.Locale; -import org.godotengine.godot.input.*; -//android.os.Build // Wrapper for native library public class GodotIO { - AssetManager am; - Godot activity; + final Activity activity; GodotEditText edit; final int SCREEN_LANDSCAPE = 0; @@ -68,7 +70,6 @@ public class GodotIO { public int last_file_id = 1; class AssetData { - public boolean eof = false; public String path; public InputStream is; @@ -79,7 +80,6 @@ public class GodotIO { 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); @@ -92,7 +92,6 @@ public class GodotIO { ad.is = am.open(path); } catch (Exception e) { - //System.out.printf("Exception on file_open: %s\n",path); return -1; } @@ -100,7 +99,6 @@ public class GodotIO { try { ad.len = ad.is.available(); } catch (Exception e) { - System.out.printf("Exception availabling on file_open: %s\n", path); return -1; } @@ -113,7 +111,6 @@ public class GodotIO { 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; @@ -122,7 +119,6 @@ public class GodotIO { 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; @@ -135,7 +131,6 @@ public class GodotIO { bytes = 0; try { - if (bytes > (int)ad.pos) { int todo = bytes - (int)ad.pos; while (todo > 0) { @@ -143,7 +138,6 @@ public class GodotIO { } ad.pos = bytes; } else if (bytes < (int)ad.pos) { - ad.is = am.open(ad.path); ad.pos = bytes; @@ -155,14 +149,12 @@ public class GodotIO { 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; @@ -172,7 +164,6 @@ public class GodotIO { 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; @@ -183,7 +174,6 @@ public class GodotIO { } 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]; @@ -192,13 +182,11 @@ public class GodotIO { 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]; } @@ -207,7 +195,6 @@ public class GodotIO { try { r = ad.is.read(buf1); } catch (IOException e) { - System.out.printf("Exception on file_read: %s\n", e); return new byte[bytes]; } @@ -219,19 +206,16 @@ public class GodotIO { 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; @@ -245,7 +229,6 @@ public class GodotIO { ///////////////////////// class AssetDir { - public String[] files; public int current; public String path; @@ -256,7 +239,6 @@ public class GodotIO { SparseArray<AssetDir> dirs; public int dir_open(String path) { - AssetDir ad = new AssetDir(); ad.current = 0; ad.path = path; @@ -269,7 +251,6 @@ public class GodotIO { return -1; } } catch (IOException e) { - System.out.printf("Exception on dir_open: %s\n", e); return -1; } @@ -308,7 +289,6 @@ public class GodotIO { } public String dir_next(int id) { - if (dirs.get(id) == null) { System.out.printf("dir_next: invalid dir id: %d\n", id); return ""; @@ -327,7 +307,6 @@ public class GodotIO { } public void dir_close(int id) { - if (dirs.get(id) == null) { System.out.printf("dir_close: invalid dir id: %d\n", id); return; @@ -336,8 +315,7 @@ public class GodotIO { dirs.remove(id); } - GodotIO(Godot p_activity) { - + GodotIO(Activity p_activity) { am = p_activity.getAssets(); activity = p_activity; //streams = new HashMap<Integer, AssetData>(); @@ -428,7 +406,6 @@ public class GodotIO { } public void audioPause(boolean p_pause) { - if (p_pause) mAudioTrack.pause(); else @@ -440,7 +417,6 @@ public class GodotIO { ///////////////////////// public int openURI(String p_uri) { - try { Log.v("MyApp", "TRYING TO OPEN URI: " + p_uri); String path = p_uri; @@ -449,7 +425,6 @@ public class GodotIO { //absolute path to filesystem, prepend file:// path = "file://" + path; if (p_uri.endsWith(".png") || p_uri.endsWith(".jpg") || p_uri.endsWith(".gif") || p_uri.endsWith(".webp")) { - type = "image/*"; } } @@ -465,18 +440,15 @@ public class GodotIO { activity.startActivity(intent); return 0; } catch (ActivityNotFoundException e) { - return 1; } } public String getDataDir() { - return activity.getFilesDir().getAbsolutePath(); } public String getLocale() { - return Locale.getDefault().toString(); } @@ -489,9 +461,9 @@ public class GodotIO { return (int)(metrics.density * 160f); } - public void showKeyboard(String p_existing_text, int p_max_input_length) { + 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_max_input_length); + edit.showKeyboard(p_existing_text, p_multiline, p_max_input_length, p_cursor_start, p_cursor_end); //InputMethodManager inputMgr = (InputMethodManager)activity.getSystemService(Context.INPUT_METHOD_SERVICE); //inputMgr.toggleSoftInput(InputMethodManager.SHOW_FORCED, 0); @@ -503,9 +475,7 @@ public class GodotIO { }; public void setScreenOrientation(int p_orientation) { - switch (p_orientation) { - case SCREEN_LANDSCAPE: { activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); } break; @@ -548,7 +518,6 @@ public class GodotIO { public static final int SYSTEM_DIR_RINGTONES = 7; public String getSystemDir(int idx) { - String what = ""; switch (idx) { case SYSTEM_DIR_DESKTOP: { @@ -593,7 +562,6 @@ public class GodotIO { public static String unique_id = ""; public String getUniqueID() { - return unique_id; } } 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 71fe822233..318e2816ff 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotLib.java @@ -33,6 +33,7 @@ package org.godotengine.godot; import android.app.Activity; import android.hardware.SensorEvent; import android.view.Surface; + import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; @@ -40,7 +41,6 @@ import javax.microedition.khronos.opengles.GL10; * Wrapper for native library */ public class GodotLib { - public static GodotIO io; static { @@ -50,13 +50,13 @@ public class GodotLib { /** * Invoked on the main thread to initialize Godot native layer. */ - public static native void initialize(Godot p_instance, Object p_asset_manager, boolean use_apk_expansion); + public static native void initialize(Activity activity, Godot p_instance, Object p_asset_manager, boolean use_apk_expansion); /** * Invoked on the main thread to clean up Godot native layer. - * @see Activity#onDestroy() + * @see androidx.fragment.app.Fragment#onDestroy() */ - public static native void ondestroy(Godot p_instance); + public static native void ondestroy(); /** * Invoked on the GL thread to complete setup for the Godot native layer logic. @@ -66,11 +66,12 @@ public class GodotLib { /** * Invoked on the GL thread when the underlying Android surface has changed size. - * @param width - * @param height + * @param p_surface + * @param p_width + * @param p_height * @see android.opengl.GLSurfaceView.Renderer#onSurfaceChanged(GL10, int, int) */ - public static native void resize(int width, int height); + public static native void resize(Surface p_surface, int p_width, int p_height); /** * Invoked on the render thread when the underlying Android surface is created or recreated. @@ -160,14 +161,14 @@ public class GodotLib { public static native void joyconnectionchanged(int p_device, boolean p_connected, String p_name); /** - * Invoked when the Android activity resumes. - * @see Activity#onResume() + * Invoked when the Android app resumes. + * @see androidx.fragment.app.Fragment#onResume() */ public static native void focusin(); /** - * Invoked when the Android activity pauses. - * @see Activity#onPause() + * Invoked when the Android app pauses. + * @see androidx.fragment.app.Fragment#onPause() */ public static native void focusout(); @@ -189,7 +190,7 @@ public class GodotLib { * @param p_method Name of the method to invoke * @param p_params Parameters to use for method invocation */ - public static native void callobject(int p_id, String p_method, Object[] p_params); + public static native void callobject(long p_id, String p_method, Object[] p_params); /** * Invoke method |p_method| on the Godot object specified by |p_id| during idle time. @@ -197,7 +198,7 @@ public class GodotLib { * @param p_method Name of the method to invoke * @param p_params Parameters to use for method invocation */ - public static native void calldeferred(int p_id, String p_method, Object[] p_params); + public static native void calldeferred(long p_id, String p_method, Object[] p_params); /** * Forward the results from a permission request. diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java index 170c433c9c..68b8a16641 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderView.java @@ -30,10 +30,11 @@ package org.godotengine.godot; +import org.godotengine.godot.input.GodotInputHandler; + import android.view.SurfaceView; public interface GodotRenderView { - abstract public SurfaceView getView(); abstract public void initInputDevices(); @@ -44,4 +45,6 @@ public interface GodotRenderView { abstract public void onActivityResumed(); abstract public void onBackPressed(); + + abstract public GodotInputHandler getInputHandler(); } diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java index 3e5bb4a4c9..64395f7d1e 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotRenderer.java @@ -30,19 +30,20 @@ package org.godotengine.godot; +import org.godotengine.godot.plugin.GodotPlugin; +import org.godotengine.godot.plugin.GodotPluginRegistry; +import org.godotengine.godot.utils.GLUtils; + import android.content.Context; import android.opengl.GLSurfaceView; + import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; -import org.godotengine.godot.plugin.GodotPlugin; -import org.godotengine.godot.plugin.GodotPluginRegistry; -import org.godotengine.godot.utils.GLUtils; /** * Godot's renderer implementation. */ class GodotRenderer implements GLSurfaceView.Renderer { - private final GodotPluginRegistry pluginRegistry; private boolean activityJustResumed = false; @@ -63,7 +64,7 @@ class GodotRenderer implements GLSurfaceView.Renderer { } public void onSurfaceChanged(GL10 gl, int width, int height) { - GodotLib.resize(width, height); + GodotLib.resize(null, width, height); for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) { plugin.onGLSurfaceChanged(gl, width, height); } diff --git a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java index 30197d5729..65708389c3 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java +++ b/platform/android/java/lib/src/org/godotengine/godot/GodotVulkanRenderView.java @@ -30,29 +30,30 @@ package org.godotengine.godot; +import org.godotengine.godot.input.GodotGestureHandler; +import org.godotengine.godot.input.GodotInputHandler; +import org.godotengine.godot.vulkan.VkRenderer; +import org.godotengine.godot.vulkan.VkSurfaceView; + import android.annotation.SuppressLint; +import android.content.Context; import android.view.GestureDetector; import android.view.KeyEvent; import android.view.MotionEvent; import android.view.SurfaceView; -import org.godotengine.godot.input.GodotGestureHandler; -import org.godotengine.godot.input.GodotInputHandler; -import org.godotengine.godot.vulkan.VkRenderer; -import org.godotengine.godot.vulkan.VkSurfaceView; public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderView { - - private final Godot mActivity; + private final Godot godot; private final GodotInputHandler mInputHandler; private final GestureDetector mGestureDetector; private final VkRenderer mRenderer; - public GodotVulkanRenderView(Godot activity) { - super(activity); + public GodotVulkanRenderView(Context context, Godot godot) { + super(context); - mActivity = activity; + this.godot = godot; mInputHandler = new GodotInputHandler(this); - mGestureDetector = new GestureDetector(mActivity, new GodotGestureHandler(this)); + mGestureDetector = new GestureDetector(context, new GodotGestureHandler(this)); mRenderer = new VkRenderer(); setFocusableInTouchMode(true); @@ -86,7 +87,12 @@ public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderV @Override public void onBackPressed() { - mActivity.onBackPressed(); + godot.onBackPressed(); + } + + @Override + public GodotInputHandler getInputHandler() { + return mInputHandler; } @SuppressLint("ClickableViewAccessibility") @@ -94,7 +100,7 @@ public class GodotVulkanRenderView extends VkSurfaceView implements GodotRenderV public boolean onTouchEvent(MotionEvent event) { super.onTouchEvent(event); mGestureDetector.onTouchEvent(event); - return mActivity.gotTouchEvent(event); + return godot.gotTouchEvent(event); } @Override diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java index 92bb118e44..6855f91f1c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotEditText.java @@ -29,17 +29,32 @@ /*************************************************************************/ package org.godotengine.godot.input; + +import org.godotengine.godot.*; + +import android.app.Activity; import android.content.Context; +import android.graphics.Point; +import android.graphics.Rect; import android.os.Handler; import android.os.Message; import android.text.InputFilter; +import android.text.InputType; import android.util.AttributeSet; +import android.view.Gravity; import android.view.KeyEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.ViewGroup.LayoutParams; +import android.view.ViewTreeObserver; +import android.view.WindowManager; import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.EditText; +import android.widget.FrameLayout; +import android.widget.PopupWindow; + import java.lang.ref.WeakReference; -import org.godotengine.godot.*; public class GodotEditText extends EditText { // =========================================================== @@ -52,9 +67,13 @@ public class GodotEditText extends EditText { // Fields // =========================================================== private GodotRenderView mRenderView; + private View mKeyboardView; + private PopupWindow mKeyboardWindow; private GodotTextInputWrapper mInputWrapper; private EditHandler sHandler = new EditHandler(this); private String mOriginText; + private int mMaxInputLength = Integer.MAX_VALUE; + private boolean mMultiline = false; private static class EditHandler extends Handler { private final WeakReference<GodotEditText> mEdit; @@ -74,24 +93,56 @@ public class GodotEditText extends EditText { // =========================================================== // Constructors // =========================================================== - public GodotEditText(final Context context) { + public GodotEditText(final Context context, final GodotRenderView view) { super(context); - initView(); + + setPadding(0, 0, 0, 0); + setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI | EditorInfo.IME_ACTION_DONE); + setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); + + mRenderView = view; + mInputWrapper = new GodotTextInputWrapper(mRenderView, this); + setOnEditorActionListener(mInputWrapper); + view.getView().requestFocus(); + + // Create a popup window with an invisible layout for the virtual keyboard, + // so the view can be resized to get the vk height without resizing the main godot view. + final FrameLayout keyboardLayout = new FrameLayout(context); + keyboardLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); + keyboardLayout.setVisibility(View.INVISIBLE); + keyboardLayout.addView(this); + mKeyboardView = keyboardLayout; + + mKeyboardWindow = new PopupWindow(keyboardLayout, LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); + mKeyboardWindow.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE); + mKeyboardWindow.setInputMethodMode(PopupWindow.INPUT_METHOD_NEEDED); + mKeyboardWindow.setFocusable(true); // for the text edit to work + mKeyboardWindow.setTouchable(false); // inputs need to go through + + keyboardLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { + @Override + public void onGlobalLayout() { + Point fullSize = new Point(); + ((Activity)mRenderView.getView().getContext()).getWindowManager().getDefaultDisplay().getSize(fullSize); + Rect gameSize = new Rect(); + mKeyboardWindow.getContentView().getWindowVisibleDisplayFrame(gameSize); + + final int keyboardHeight = fullSize.y - gameSize.bottom; + GodotLib.setVirtualKeyboardHeight(keyboardHeight); + } + }); } - public GodotEditText(final Context context, final AttributeSet attrs) { - super(context, attrs); - initView(); + public void onInitView() { + mKeyboardWindow.showAtLocation(mRenderView.getView(), Gravity.NO_GRAVITY, 0, 0); } - public GodotEditText(final Context context, final AttributeSet attrs, final int defStyle) { - super(context, attrs, defStyle); - initView(); + public void onDestroyView() { + mKeyboardWindow.dismiss(); } - protected void initView() { - setPadding(0, 0, 0, 0); - setImeOptions(EditorInfo.IME_FLAG_NO_EXTRACT_UI); + public boolean isMultiline() { + return mMultiline; } private void handleMessage(final Message msg) { @@ -101,12 +152,25 @@ public class GodotEditText extends EditText { String text = edit.mOriginText; if (edit.requestFocus()) { edit.removeTextChangedListener(edit.mInputWrapper); + setMaxInputLength(edit); edit.setText(""); edit.append(text); + if (msg.arg2 != -1) { + edit.setSelection(msg.arg1, msg.arg2); + edit.mInputWrapper.setSelection(true); + } else { + edit.mInputWrapper.setSelection(false); + } + + int inputType = InputType.TYPE_CLASS_TEXT; + if (edit.isMultiline()) { + inputType |= InputType.TYPE_TEXT_FLAG_MULTI_LINE; + } + edit.setInputType(inputType); + edit.mInputWrapper.setOriginText(text); edit.addTextChangedListener(edit.mInputWrapper); - setMaxInputLength(edit, msg.arg1); - final InputMethodManager imm = (InputMethodManager)mRenderView.getView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + final InputMethodManager imm = (InputMethodManager)mKeyboardView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.showSoftInput(edit, 0); } } break; @@ -115,32 +179,17 @@ public class GodotEditText extends EditText { GodotEditText edit = (GodotEditText)msg.obj; edit.removeTextChangedListener(mInputWrapper); - final InputMethodManager imm = (InputMethodManager)mRenderView.getView().getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + final InputMethodManager imm = (InputMethodManager)mKeyboardView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE); imm.hideSoftInputFromWindow(edit.getWindowToken(), 0); edit.mRenderView.getView().requestFocus(); } break; } } - private void setMaxInputLength(EditText p_edit_text, int p_max_input_length) { - if (p_max_input_length > 0) { - InputFilter[] filters = new InputFilter[1]; - filters[0] = new InputFilter.LengthFilter(p_max_input_length); - p_edit_text.setFilters(filters); - } else { - p_edit_text.setFilters(new InputFilter[] {}); - } - } - - // =========================================================== - // Getter & Setter - // =========================================================== - public void setView(final GodotRenderView view) { - mRenderView = view; - if (mInputWrapper == null) - mInputWrapper = new GodotTextInputWrapper(mRenderView, this); - setOnEditorActionListener(mInputWrapper); - view.getView().requestFocus(); + private void setMaxInputLength(EditText p_edit_text) { + InputFilter[] filters = new InputFilter[1]; + filters[0] = new InputFilter.LengthFilter(this.mMaxInputLength); + p_edit_text.setFilters(filters); } // =========================================================== @@ -148,26 +197,60 @@ public class GodotEditText extends EditText { // =========================================================== @Override public boolean onKeyDown(final int keyCode, final KeyEvent keyEvent) { - super.onKeyDown(keyCode, keyEvent); - - /* Let GlSurfaceView get focus if back key is input. */ + /* Let SurfaceView get focus if back key is input. */ if (keyCode == KeyEvent.KEYCODE_BACK) { mRenderView.getView().requestFocus(); } - return true; + // pass event to godot in special cases + if (needHandlingInGodot(keyCode, keyEvent) && mRenderView.getInputHandler().onKeyDown(keyCode, keyEvent)) { + return true; + } else { + return super.onKeyDown(keyCode, keyEvent); + } + } + + @Override + public boolean onKeyUp(int keyCode, KeyEvent keyEvent) { + if (needHandlingInGodot(keyCode, keyEvent) && mRenderView.getInputHandler().onKeyUp(keyCode, keyEvent)) { + return true; + } else { + return super.onKeyUp(keyCode, keyEvent); + } + } + + private boolean needHandlingInGodot(int keyCode, KeyEvent keyEvent) { + boolean isArrowKey = keyCode == KeyEvent.KEYCODE_DPAD_UP || keyCode == KeyEvent.KEYCODE_DPAD_DOWN || + keyCode == KeyEvent.KEYCODE_DPAD_LEFT || keyCode == KeyEvent.KEYCODE_DPAD_RIGHT; + boolean isModifiedKey = keyEvent.isAltPressed() || keyEvent.isCtrlPressed() || keyEvent.isSymPressed() || + keyEvent.isFunctionPressed() || keyEvent.isMetaPressed(); + return isArrowKey || keyCode == KeyEvent.KEYCODE_TAB || KeyEvent.isModifierKey(keyCode) || + isModifiedKey; } // =========================================================== // Methods // =========================================================== - public void showKeyboard(String p_existing_text, int p_max_input_length) { - mOriginText = p_existing_text; + public void showKeyboard(String p_existing_text, boolean p_multiline, int p_max_input_length, int p_cursor_start, int p_cursor_end) { + int maxInputLength = (p_max_input_length <= 0) ? Integer.MAX_VALUE : p_max_input_length; + if (p_cursor_start == -1) { // cursor position not given + this.mOriginText = p_existing_text; + this.mMaxInputLength = maxInputLength; + } else if (p_cursor_end == -1) { // not text selection + this.mOriginText = p_existing_text.substring(0, p_cursor_start); + this.mMaxInputLength = maxInputLength - (p_existing_text.length() - p_cursor_start); + } else { + this.mOriginText = p_existing_text.substring(0, p_cursor_end); + this.mMaxInputLength = maxInputLength - (p_existing_text.length() - p_cursor_end); + } + + this.mMultiline = p_multiline; final Message msg = new Message(); msg.what = HANDLER_OPEN_IME_KEYBOARD; msg.obj = this; - msg.arg1 = p_max_input_length; + msg.arg1 = p_cursor_start; + msg.arg2 = p_cursor_end; sHandler.sendMessage(msg); } diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java index b1e0f66373..1c9a683bbd 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotGestureHandler.java @@ -30,18 +30,18 @@ package org.godotengine.godot.input; +import org.godotengine.godot.GodotLib; +import org.godotengine.godot.GodotRenderView; + import android.util.Log; import android.view.GestureDetector; import android.view.MotionEvent; -import org.godotengine.godot.GodotLib; -import org.godotengine.godot.GodotRenderView; /** * Handles gesture input related events for the {@link GodotRenderView} view. * https://developer.android.com/reference/android/view/GestureDetector.SimpleOnGestureListener */ public class GodotGestureHandler extends GestureDetector.SimpleOnGestureListener { - private final GodotRenderView mRenderView; public GodotGestureHandler(GodotRenderView godotView) { diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java index 0e4fc65119..9abd65cc67 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotInputHandler.java @@ -32,24 +32,25 @@ package org.godotengine.godot.input; import static org.godotengine.godot.utils.GLUtils.DEBUG; +import org.godotengine.godot.GodotLib; +import org.godotengine.godot.GodotRenderView; +import org.godotengine.godot.input.InputManagerCompat.InputDeviceListener; + import android.util.Log; import android.view.InputDevice; import android.view.InputDevice.MotionRange; import android.view.KeyEvent; import android.view.MotionEvent; + import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.List; -import org.godotengine.godot.GodotLib; -import org.godotengine.godot.GodotRenderView; -import org.godotengine.godot.input.InputManagerCompat.InputDeviceListener; /** * Handles input related events for the {@link GodotRenderView} view. */ public class GodotInputHandler implements InputDeviceListener { - private final ArrayList<Joystick> mJoysticksDevices = new ArrayList<Joystick>(); private final GodotRenderView mRenderView; @@ -84,7 +85,6 @@ public class GodotInputHandler implements InputDeviceListener { int source = event.getSource(); if (isKeyEvent_GameDevice(source)) { - final int button = getGodotButton(keyCode); final int device_id = findJoystickDevice(event.getDeviceId()); @@ -127,7 +127,6 @@ public class GodotInputHandler implements InputDeviceListener { //Log.e(TAG, String.format("Key down! source %d, device %d, joystick %d, %d, %d", event.getDeviceId(), source, (source & InputDevice.SOURCE_JOYSTICK), (source & InputDevice.SOURCE_DPAD), (source & InputDevice.SOURCE_GAMEPAD))); if (isKeyEvent_GameDevice(source)) { - if (event.getRepeatCount() > 0) // ignore key echo return true; @@ -159,7 +158,6 @@ public class GodotInputHandler implements InputDeviceListener { public boolean onGenericMotionEvent(MotionEvent event) { if ((event.getSource() & InputDevice.SOURCE_JOYSTICK) == InputDevice.SOURCE_JOYSTICK && event.getAction() == MotionEvent.ACTION_MOVE) { - final int device_id = findJoystickDevice(event.getDeviceId()); // Check if the device exists diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java index e12ff266bf..4dd1054738 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/GodotTextInputWrapper.java @@ -29,6 +29,9 @@ /*************************************************************************/ package org.godotengine.godot.input; + +import org.godotengine.godot.*; + import android.content.Context; import android.text.Editable; import android.text.TextWatcher; @@ -37,7 +40,6 @@ import android.view.inputmethod.EditorInfo; import android.view.inputmethod.InputMethodManager; import android.widget.TextView; import android.widget.TextView.OnEditorActionListener; -import org.godotengine.godot.*; public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListener { // =========================================================== @@ -51,6 +53,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene private final GodotRenderView mRenderView; private final GodotEditText mEdit; private String mOriginText; + private boolean mHasSelection; // =========================================================== // Constructors @@ -75,6 +78,10 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene mOriginText = originText; } + public void setSelection(boolean selection) { + mHasSelection = selection; + } + // =========================================================== // Methods for/from SuperClass/Interfaces // =========================================================== @@ -93,6 +100,11 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene for (int i = 0; i < count; ++i) { GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, true); GodotLib.key(KeyEvent.KEYCODE_DEL, KeyEvent.KEYCODE_DEL, 0, false); + + if (mHasSelection) { + mHasSelection = false; + break; + } } } }); @@ -111,7 +123,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene public void run() { for (int i = 0; i < count; ++i) { int key = newChars[i]; - if (key == '\n') { + if ((key == '\n') && !mEdit.isMultiline()) { // Return keys are handled through action events continue; } @@ -139,7 +151,7 @@ public class GodotTextInputWrapper implements TextWatcher, OnEditorActionListene }); } - if (pActionID == EditorInfo.IME_NULL) { + if (pActionID == EditorInfo.IME_ACTION_DONE) { // Enter key has been pressed GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, true); GodotLib.key(KeyEvent.KEYCODE_ENTER, KeyEvent.KEYCODE_ENTER, 0, false); diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerCompat.java b/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerCompat.java index 4042c42e9d..62810ad3a4 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerCompat.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerCompat.java @@ -120,7 +120,6 @@ public interface InputManagerCompat { * Use this to construct a compatible InputManager. */ public static class Factory { - /** * Constructs and returns a compatible InputManger * diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerV16.java b/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerV16.java index e4bafa7ff9..61828dccae 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerV16.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/InputManagerV16.java @@ -23,12 +23,12 @@ import android.os.Build; import android.os.Handler; import android.view.InputDevice; import android.view.MotionEvent; + import java.util.HashMap; import java.util.Map; @TargetApi(Build.VERSION_CODES.JELLY_BEAN) public class InputManagerV16 implements InputManagerCompat { - private final InputManager mInputManager; private final Map<InputManagerCompat.InputDeviceListener, V16InputDeviceListener> mListeners; diff --git a/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java index 0c1bdb32aa..1f3fe1e527 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java +++ b/platform/android/java/lib/src/org/godotengine/godot/input/Joystick.java @@ -31,6 +31,7 @@ package org.godotengine.godot.input; import android.view.InputDevice.MotionRange; + import java.util.ArrayList; /** diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java index a051164d15..93c204935c 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java +++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPlugin.java @@ -30,24 +30,28 @@ package org.godotengine.godot.plugin; +import org.godotengine.godot.BuildConfig; +import org.godotengine.godot.Godot; + import android.app.Activity; import android.content.Intent; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.text.TextUtils; +import android.os.Bundle; import android.util.Log; import android.view.Surface; import android.view.View; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; + import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.opengles.GL10; -import org.godotengine.godot.BuildConfig; -import org.godotengine.godot.Godot; /** * Base class for the Godot Android plugins. @@ -73,7 +77,6 @@ import org.godotengine.godot.Godot; * 'godot/plugin/v1/[PluginName]/' */ public abstract class GodotPlugin { - private static final String TAG = GodotPlugin.class.getSimpleName(); private final Godot godot; @@ -91,6 +94,14 @@ public abstract class GodotPlugin { } /** + * Provides access to the underlying {@link Activity}. + */ + @Nullable + protected Activity getActivity() { + return godot.getActivity(); + } + + /** * Register the plugin with Godot native code. * * This method is invoked on the render thread. @@ -143,13 +154,14 @@ public abstract class GodotPlugin { * Invoked once during the Godot Android initialization process after creation of the * {@link org.godotengine.godot.GodotView} view. * <p> - * This method should be overridden by descendants of this class that would like to add - * their view/layout to the Godot view hierarchy. + * The plugin can return a non-null {@link View} layout in order to add it to the Godot view + * hierarchy. * - * @return the view to be included; null if no views should be included. + * @see Activity#onCreate(Bundle) + * @return the plugin's view to be included; null if no views should be included. */ @Nullable - public View onMainCreateView(Activity activity) { + public View onMainCreate(Activity activity) { return null; } diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java index e13a9c15d8..1c2d1a6563 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java +++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/GodotPluginRegistry.java @@ -30,26 +30,28 @@ package org.godotengine.godot.plugin; +import org.godotengine.godot.Godot; + +import android.app.Activity; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.Bundle; -import android.support.annotation.Nullable; import android.text.TextUtils; import android.util.Log; + +import androidx.annotation.Nullable; + import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; import java.util.Collection; import java.util.HashSet; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; -import org.godotengine.godot.Godot; /** * Registry used to load and access the registered Godot Android plugins. */ public final class GodotPluginRegistry { - private static final String TAG = GodotPluginRegistry.class.getSimpleName(); private static final String GODOT_PLUGIN_V1_NAME_PREFIX = "org.godotengine.plugin.v1."; @@ -57,7 +59,9 @@ public final class GodotPluginRegistry { /** * Name for the metadata containing the list of Godot plugins to enable. */ - private static final String GODOT_ENABLED_PLUGINS_LABEL = "custom_template_plugins"; + private static final String GODOT_ENABLED_PLUGINS_LABEL = "plugins"; + + private static final String PLUGIN_VALUE_SEPARATOR_REGEX = "\\|"; private static GodotPluginRegistry instance; private final ConcurrentHashMap<String, GodotPlugin> registry; @@ -118,22 +122,24 @@ public final class GodotPluginRegistry { private void loadPlugins(Godot godot) { try { - ApplicationInfo appInfo = godot + final Activity activity = godot.getActivity(); + ApplicationInfo appInfo = activity .getPackageManager() - .getApplicationInfo(godot.getPackageName(), PackageManager.GET_META_DATA); + .getApplicationInfo(activity.getPackageName(), + PackageManager.GET_META_DATA); Bundle metaData = appInfo.metaData; if (metaData == null || metaData.isEmpty()) { return; } // When using the Godot editor for building and exporting the apk, this is used to check - // which plugins to enable since the custom build template may contain prebuilt plugins. + // which plugins to enable. // When using a custom process to generate the apk, the metadata is not needed since // it's assumed that the developer is aware of the dependencies included in the apk. final Set<String> enabledPluginsSet; if (metaData.containsKey(GODOT_ENABLED_PLUGINS_LABEL)) { String enabledPlugins = metaData.getString(GODOT_ENABLED_PLUGINS_LABEL, ""); - String[] enabledPluginsList = enabledPlugins.split(","); + String[] enabledPluginsList = enabledPlugins.split(PLUGIN_VALUE_SEPARATOR_REGEX); if (enabledPluginsList.length == 0) { // No plugins to enable. Aborting early. return; @@ -157,6 +163,8 @@ public final class GodotPluginRegistry { continue; } + Log.i(TAG, "Initializing Godot plugin " + pluginName); + // Retrieve the plugin class full name. String pluginHandleClassFullName = metaData.getString(metaDataName); if (!TextUtils.isEmpty(pluginHandleClassFullName)) { @@ -176,6 +184,7 @@ public final class GodotPluginRegistry { "Meta-data plugin name does not match the value returned by the plugin handle: " + pluginName + " =/= " + pluginHandle.getPluginName()); } registry.put(pluginName, pluginHandle); + Log.i(TAG, "Completed initialization for Godot plugin " + pluginHandle.getPluginName()); } catch (ClassNotFoundException e) { Log.w(TAG, "Unable to load Godot plugin " + pluginName, e); } catch (IllegalAccessException e) { diff --git a/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java index f907706889..f82c4d3fa0 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java +++ b/platform/android/java/lib/src/org/godotengine/godot/plugin/SignalInfo.java @@ -5,8 +5,8 @@ /* GODOT ENGINE */ /* https://godotengine.org */ /*************************************************************************/ -/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ -/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ +/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur. */ +/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md). */ /* */ /* Permission is hereby granted, free of charge, to any person obtaining */ /* a copy of this software and associated documentation files (the */ @@ -30,15 +30,16 @@ package org.godotengine.godot.plugin; -import android.support.annotation.NonNull; import android.text.TextUtils; + +import androidx.annotation.NonNull; + import java.util.Arrays; /** * Store information about a {@link GodotPlugin}'s signal. */ public final class SignalInfo { - private final String name; private final Class<?>[] paramTypes; private final String[] paramTypesNames; diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java b/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java index bc0e565774..acc9c4981b 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/Crypt.java @@ -34,7 +34,6 @@ import java.security.MessageDigest; import java.util.Random; public class Crypt { - public static String md5(String input) { try { // Create MD5 Hash diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java index 9d29551f89..82420eda79 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/GLUtils.java @@ -31,6 +31,7 @@ package org.godotengine.godot.utils; import android.util.Log; + import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLDisplay; @@ -39,7 +40,6 @@ import javax.microedition.khronos.egl.EGLDisplay; * Contains GL utilities methods. */ public class GLUtils { - private static final String TAG = GLUtils.class.getSimpleName(); public static final boolean DEBUG = false; diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java b/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java index 011d426c7e..c89118ad55 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/GodotNetUtils.java @@ -30,10 +30,10 @@ package org.godotengine.godot.utils; +import android.app.Activity; import android.content.Context; import android.net.wifi.WifiManager; import android.util.Log; -import org.godotengine.godot.Godot; /** * This class handles Android-specific networking functions. @@ -41,11 +41,10 @@ import org.godotengine.godot.Godot; * to receive broadcast and multicast packets. */ public class GodotNetUtils { - /* A single, reference counted, multicast lock, or null if permission CHANGE_WIFI_MULTICAST_STATE is missing */ private WifiManager.MulticastLock multicastLock; - public GodotNetUtils(Godot p_activity) { + public GodotNetUtils(Activity p_activity) { if (PermissionsUtil.hasManifestPermission(p_activity, "android.permission.CHANGE_WIFI_MULTICAST_STATE")) { WifiManager wifi = (WifiManager)p_activity.getApplicationContext().getSystemService(Context.WIFI_SERVICE); multicastLock = wifi.createMulticastLock("GodotMulticastLock"); diff --git a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java index 7cf32b00fe..7104baf86e 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java +++ b/platform/android/java/lib/src/org/godotengine/godot/utils/PermissionsUtil.java @@ -31,20 +31,24 @@ package org.godotengine.godot.utils; import android.Manifest; +import android.app.Activity; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.content.pm.PermissionInfo; import android.os.Build; -import android.support.v4.content.ContextCompat; +import android.util.Log; + +import androidx.core.content.ContextCompat; + import java.util.ArrayList; import java.util.List; -import org.godotengine.godot.Godot; /** * This class includes utility functions for Android permissions related operations. * @author Cagdas Caglak <cagdascaglak@gmail.com> */ public final class PermissionsUtil { + private static final String TAG = PermissionsUtil.class.getSimpleName(); static final int REQUEST_RECORD_AUDIO_PERMISSION = 1; static final int REQUEST_CAMERA_PERMISSION = 2; @@ -60,7 +64,7 @@ public final class PermissionsUtil { * @param activity the caller activity for this method. * @return true/false. "true" if permission was granted otherwise returns "false". */ - public static boolean requestPermission(String name, Godot activity) { + public static boolean requestPermission(String name, Activity activity) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { // Not necessary, asked on install already return true; @@ -88,7 +92,7 @@ public final class PermissionsUtil { * @param activity the caller activity for this method. * @return true/false. "true" if all permissions were granted otherwise returns "false". */ - public static boolean requestManifestPermissions(Godot activity) { + public static boolean requestManifestPermissions(Activity activity) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { return true; } @@ -113,8 +117,8 @@ public final class PermissionsUtil { dangerousPermissions.add(manifestPermission); } } catch (PackageManager.NameNotFoundException e) { - e.printStackTrace(); - return false; + // Skip this permission and continue. + Log.w(TAG, "Unable to identify permission " + manifestPermission, e); } } @@ -133,7 +137,7 @@ public final class PermissionsUtil { * @param activity the caller activity for this method. * @return granted permissions list */ - public static String[] getGrantedPermissions(Godot activity) { + public static String[] getGrantedPermissions(Activity activity) { String[] manifestPermissions; try { manifestPermissions = getManifestPermissions(activity); @@ -153,8 +157,8 @@ public final class PermissionsUtil { dangerousPermissions.add(manifestPermission); } } catch (PackageManager.NameNotFoundException e) { - e.printStackTrace(); - return new String[0]; + // Skip this permission and continue. + Log.w(TAG, "Unable to identify permission " + manifestPermission, e); } } @@ -167,7 +171,7 @@ public final class PermissionsUtil { * @param permission the permession to look for in the manifest file. * @return "true" if the permission is in the manifest file of the activity, "false" otherwise. */ - public static boolean hasManifestPermission(Godot activity, String permission) { + public static boolean hasManifestPermission(Activity activity, String permission) { try { for (String p : getManifestPermissions(activity)) { if (permission.equals(p)) @@ -185,7 +189,7 @@ public final class PermissionsUtil { * @return manifest permissions list * @throws PackageManager.NameNotFoundException the exception is thrown when a given package, application, or component name cannot be found. */ - private static String[] getManifestPermissions(Godot activity) throws PackageManager.NameNotFoundException { + private static String[] getManifestPermissions(Activity activity) throws PackageManager.NameNotFoundException { PackageManager packageManager = activity.getPackageManager(); PackageInfo packageInfo = packageManager.getPackageInfo(activity.getPackageName(), PackageManager.GET_PERMISSIONS); if (packageInfo.requestedPermissions == null) @@ -200,7 +204,7 @@ public final class PermissionsUtil { * @return permission info object * @throws PackageManager.NameNotFoundException the exception is thrown when a given package, application, or component name cannot be found. */ - private static PermissionInfo getPermissionInfo(Godot activity, String permission) throws PackageManager.NameNotFoundException { + private static PermissionInfo getPermissionInfo(Activity activity, String permission) throws PackageManager.NameNotFoundException { PackageManager packageManager = activity.getPackageManager(); return packageManager.getPermissionInfo(permission, 0); } diff --git a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt index 608ad48df9..7fa8e3b4e5 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt +++ b/platform/android/java/lib/src/org/godotengine/godot/vulkan/VkRenderer.kt @@ -59,9 +59,7 @@ internal class VkRenderer { * Called when the surface is created and signals the beginning of rendering. */ fun onVkSurfaceCreated(surface: Surface) { - // TODO: properly implement surface re-creation: - // GodotLib.newcontext should be called here once it's done. - //GodotLib.newcontext(surface, false) + GodotLib.newcontext(surface, false) for (plugin in pluginRegistry.getAllPlugins()) { plugin.onVkSurfaceCreated(surface) @@ -72,13 +70,8 @@ internal class VkRenderer { * Called after the surface is created and whenever its size changes. */ fun onVkSurfaceChanged(surface: Surface, width: Int, height: Int) { - GodotLib.resize(width, height) - - // TODO: properly implement surface re-creation: - // Update the native renderer instead of restarting the app. - // GodotLib.newcontext should not be called here once it's done. - GodotLib.newcontext(surface, false) - + GodotLib.resize(surface, width, height) + for (plugin in pluginRegistry.getAllPlugins()) { plugin.onVkSurfaceChanged(surface, width, height) } diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java index 9209d6ccf2..819bcccdf1 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrConfigChooser.java @@ -32,6 +32,7 @@ package org.godotengine.godot.xr.ovr; import android.opengl.EGLExt; import android.opengl.GLSurfaceView; + import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLDisplay; @@ -40,7 +41,6 @@ import javax.microedition.khronos.egl.EGLDisplay; * EGL config chooser for the Oculus Mobile VR SDK. */ public class OvrConfigChooser implements GLSurfaceView.EGLConfigChooser { - private static final int[] CONFIG_ATTRIBS = { EGL10.EGL_RED_SIZE, 8, EGL10.EGL_GREEN_SIZE, 8, diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java index 36f4416df2..2d9b921466 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrContextFactory.java @@ -32,6 +32,7 @@ package org.godotengine.godot.xr.ovr; import android.opengl.EGL14; import android.opengl.GLSurfaceView; + import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLContext; @@ -41,7 +42,6 @@ import javax.microedition.khronos.egl.EGLDisplay; * EGL Context factory for the Oculus mobile VR SDK. */ public class OvrContextFactory implements GLSurfaceView.EGLContextFactory { - private static final int[] CONTEXT_ATTRIBS = { EGL14.EGL_CONTEXT_CLIENT_VERSION, 3, EGL10.EGL_NONE }; diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java index b2aa130f37..43c7f0f966 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/ovr/OvrWindowSurfaceFactory.java @@ -31,6 +31,7 @@ package org.godotengine.godot.xr.ovr; import android.opengl.GLSurfaceView; + import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLDisplay; @@ -40,7 +41,6 @@ import javax.microedition.khronos.egl.EGLSurface; * EGL window surface factory for the Oculus mobile VR SDK. */ public class OvrWindowSurfaceFactory implements GLSurfaceView.EGLWindowSurfaceFactory { - private final static int[] SURFACE_ATTRIBS = { EGL10.EGL_WIDTH, 16, EGL10.EGL_HEIGHT, 16, diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java index 8409e37f8f..54672db282 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularConfigChooser.java @@ -30,17 +30,18 @@ package org.godotengine.godot.xr.regular; +import org.godotengine.godot.utils.GLUtils; + import android.opengl.GLSurfaceView; + import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLDisplay; -import org.godotengine.godot.utils.GLUtils; /** * Used to select the egl config for pancake games. */ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser { - private static final String TAG = RegularConfigChooser.class.getSimpleName(); private int[] mValue = new int[1]; @@ -72,7 +73,6 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser { } public EGLConfig chooseConfig(EGL10 egl, EGLDisplay display) { - /* Get the number of minimally matching EGL configurations */ int[] num_config = new int[1]; @@ -127,7 +127,6 @@ public class RegularConfigChooser implements GLSurfaceView.EGLConfigChooser { private int findConfigAttrib(EGL10 egl, EGLDisplay display, EGLConfig config, int attribute, int defaultValue) { - if (egl.eglGetConfigAttrib(display, config, attribute, mValue)) { return mValue[0]; } diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java index 31cf696195..126f3ad5f5 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularContextFactory.java @@ -30,14 +30,16 @@ package org.godotengine.godot.xr.regular; +import org.godotengine.godot.GodotLib; +import org.godotengine.godot.utils.GLUtils; + import android.opengl.GLSurfaceView; import android.util.Log; + import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLContext; import javax.microedition.khronos.egl.EGLDisplay; -import org.godotengine.godot.GodotLib; -import org.godotengine.godot.utils.GLUtils; /** * Factory used to setup the opengl context for pancake games. diff --git a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java index 71fcf06020..c83c47bed7 100644 --- a/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java +++ b/platform/android/java/lib/src/org/godotengine/godot/xr/regular/RegularFallbackConfigChooser.java @@ -30,15 +30,16 @@ package org.godotengine.godot.xr.regular; +import org.godotengine.godot.utils.GLUtils; + import android.util.Log; + import javax.microedition.khronos.egl.EGL10; import javax.microedition.khronos.egl.EGLConfig; import javax.microedition.khronos.egl.EGLDisplay; -import org.godotengine.godot.utils.GLUtils; /* Fallback if 32bit View is not supported*/ public class RegularFallbackConfigChooser extends RegularConfigChooser { - private static final String TAG = RegularFallbackConfigChooser.class.getSimpleName(); private RegularConfigChooser fallback; |