Revert "Enable the ability to use Godot as a subview within an Android app"

This reverts commit 920639511d.

The changes are good, this revert is only done for release management reasons
as we want this feature to get more testing before making it in a stable build,
but a 3.2.3 release is imminent to handle some regressions in 3.2.2.

This will be re-committed in a 3.2-based feature branch, and we'll merge it
again once we're confident about it (probably for 3.2.4).
This commit is contained in:
Rémi Verschelde 2020-07-10 08:25:01 +02:00
parent 5854bf4696
commit 0246a1a276
16 changed files with 226 additions and 340 deletions

View file

@ -30,11 +30,11 @@
package com.godot.game;
import org.godotengine.godot.FullScreenGodotApp;
import org.godotengine.godot.Godot;
/**
* Template activity for Godot Android custom builds.
* Feel free to extend and modify this class for your custom logic.
*/
public class GodotApp extends FullScreenGodotApp {
public class GodotApp extends Godot {
}

View file

@ -1,5 +0,0 @@
<?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" />

View file

@ -1,80 +0,0 @@
/*************************************************************************/
/* 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);
}
}

View file

@ -30,9 +30,6 @@
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;
@ -73,7 +70,6 @@ import android.os.Vibrator;
import android.provider.Settings.Secure;
import android.view.Display;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
@ -91,7 +87,7 @@ import androidx.annotation.CallSuper;
import androidx.annotation.Keep;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import com.google.android.vending.expansion.downloader.DownloadProgressInfo;
import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller;
@ -113,7 +109,7 @@ import java.util.Locale;
import javax.microedition.khronos.opengles.GL10;
public class Godot extends Fragment implements SensorEventListener, IDownloaderClient {
public abstract class Godot extends FragmentActivity implements SensorEventListener, IDownloaderClient {
static final int MAX_SINGLETONS = 64;
private IStub mDownloaderClientStub;
@ -146,6 +142,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
static private Intent mCurrentIntent;
@Override
public void onNewIntent(Intent intent) {
mCurrentIntent = intent;
}
@ -248,7 +245,6 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
private String[] command_line;
private boolean use_apk_expansion;
private ViewGroup containerLayout;
public GodotView mView;
private boolean godot_initialized = false;
@ -270,7 +266,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
public ResultCallback result_callback;
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (result_callback != null) {
result_callback.callback(requestCode, resultCode, data);
result_callback = null;
@ -316,18 +312,18 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
private void onVideoInit() {
boolean use_gl3 = getGLESVersionCode() >= 0x00030000;
final Activity activity = getActivity();
containerLayout = new FrameLayout(activity);
containerLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
final FrameLayout layout = new FrameLayout(this);
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
setContentView(layout);
// GodotEditText layout
GodotEditText edittext = new GodotEditText(activity);
GodotEditText edittext = new GodotEditText(this);
edittext.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
// ...add to FrameLayout
containerLayout.addView(edittext);
layout.addView(edittext);
mView = new GodotView(activity, this, xrMode, use_gl3, use_32_bits, use_debug_opengl);
containerLayout.addView(mView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
mView = new GodotView(this, xrMode, use_gl3, use_32_bits, use_debug_opengl);
layout.addView(mView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
edittext.setView(mView);
io.setEdit(edittext);
@ -335,7 +331,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
@Override
public void onGlobalLayout() {
Point fullSize = new Point();
activity.getWindowManager().getDefaultDisplay().getSize(fullSize);
getWindowManager().getDefaultDisplay().getSize(fullSize);
Rect gameSize = new Rect();
mView.getWindowVisibleDisplayFrame(gameSize);
@ -363,9 +359,9 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
public void run() {
// Include the non-null views returned in the Godot view hierarchy.
for (int i = 0; i < singleton_count; i++) {
View view = singletons[i].onMainCreateView(activity);
View view = singletons[i].onMainCreateView(Godot.this);
if (view != null) {
containerLayout.addView(view);
layout.addView(view);
}
}
}
@ -375,9 +371,9 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
// Include the returned non-null views in the Godot view hierarchy.
for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) {
View pluginView = plugin.onMainCreate(activity);
View pluginView = plugin.onMainCreate(this);
if (pluginView != null) {
containerLayout.addView(pluginView);
layout.addView(pluginView);
}
}
}
@ -387,9 +383,9 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
@Override
public void run() {
if (p_enabled) {
getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
} else {
getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
}
});
@ -403,7 +399,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
@Keep
private void vibrate(int durationMs) {
if (requestPermission("VIBRATE")) {
Vibrator v = (Vibrator)getContext().getSystemService(Context.VIBRATOR_SERVICE);
Vibrator v = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
if (v != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
v.vibrate(VibrationEffect.createOneShot(durationMs, VibrationEffect.DEFAULT_AMPLITUDE));
@ -427,16 +423,13 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
// 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.
//
final Activity activity = getActivity();
if (activity != null) {
Bundle args = new Bundle();
args.putParcelable("intent", mCurrentIntent);
activity.startInstrumentation(new ComponentName(activity, GodotInstrumentation.class), null, args);
}
Bundle args = new Bundle();
args.putParcelable("intent", mCurrentIntent);
startInstrumentation(new ComponentName(this, GodotInstrumentation.class), null, args);
}
public void alert(final String message, final String title) {
final Activity activity = getActivity();
final Activity activity = this;
runOnUiThread(new Runnable() {
@Override
public void run() {
@ -456,7 +449,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
public int getGLESVersionCode() {
ActivityManager am = (ActivityManager)getContext().getSystemService(Context.ACTIVITY_SERVICE);
ActivityManager am = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE);
ConfigurationInfo deviceInfo = am.getDeviceConfigurationInfo();
return deviceInfo.reqGlEsVersion;
}
@ -465,7 +458,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
protected String[] getCommandLine() {
InputStream is;
try {
is = getActivity().getAssets().open("_cl_");
is = getAssets().open("_cl_");
byte[] len = new byte[4];
int r = is.read(len);
if (r < 4) {
@ -545,12 +538,11 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
command_line = new_cmdline;
}
final Activity activity = getActivity();
io = new GodotIO(activity);
io.unique_id = Secure.getString(activity.getContentResolver(), Secure.ANDROID_ID);
io = new GodotIO(this);
io.unique_id = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
GodotLib.io = io;
netUtils = new GodotNetUtils(activity);
mSensorManager = (SensorManager)activity.getSystemService(Context.SENSOR_SERVICE);
netUtils = new GodotNetUtils(this);
mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME);
mGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
@ -560,7 +552,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME);
GodotLib.initialize(activity, this, activity.getAssets(), use_apk_expansion);
GodotLib.initialize(this, getAssets(), use_apk_expansion);
result_callback = null;
@ -574,151 +566,151 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle) {
final Activity activity = getActivity();
Window window = activity.getWindow();
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
Window window = getWindow();
window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
mClipboard = (ClipboardManager)activity.getSystemService(Context.CLIPBOARD_SERVICE);
mClipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE);
pluginRegistry = GodotPluginRegistry.initializePluginRegistry(this);
//check for apk expansion API
boolean md5mismatch = false;
command_line = getCommandLine();
String main_pack_md5 = null;
String main_pack_key = null;
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>();
List<String> new_args = new LinkedList<String>();
for (int i = 0; i < command_line.length; i++) {
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);
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();
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]);
}
} 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 (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(getContext());
expansion_pack_path += "/main." + activity.getPackageManager().getPackageInfo(activity.getPackageName(), 0).versionCode + "." + activity.getPackageName() + ".obb";
} catch (Exception e) {
e.printStackTrace();
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
}
File f = new File(expansion_pack_path);
boolean pack_valid = true;
if (!f.exists()) {
pack_valid = false;
} else if (obbIsCorrupted(expansion_pack_path, main_pack_md5)) {
pack_valid = false;
// Build the full path to the app's expansion files
try {
f.delete();
expansion_pack_path = Helpers.getSaveFilePath(getApplicationContext());
expansion_pack_path += "/main." + getPackageManager().getPackageInfo(getPackageName(), 0).versionCode + "." + this.getPackageName() + ".obb";
} catch (Exception e) {
e.printStackTrace();
}
}
if (!pack_valid) {
File f = new File(expansion_pack_path);
Intent notifierIntent = new Intent(activity, activity.getClass());
notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TOP);
boolean pack_valid = true;
PendingIntent pendingIntent = PendingIntent.getActivity(activity, 0,
notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if (!f.exists()) {
int startResult;
try {
startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(
getContext(),
pendingIntent,
GodotDownloaderService.class);
pack_valid = false;
if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) {
// This is where you do set up to display the download
// progress (next step)
mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this,
} 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);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT);
int startResult;
try {
startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(
getApplicationContext(),
pendingIntent,
GodotDownloaderService.class);
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);
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);
return downloadingExpansionView;
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
}
} catch (NameNotFoundException e) {
// TODO Auto-generated catch block
}
}
}
mCurrentIntent = activity.getIntent();
mCurrentIntent = getIntent();
initializeGodot();
return containerLayout;
}
@Override
public void onDestroy() {
protected void onDestroy() {
for (int i = 0; i < singleton_count; i++) {
singletons[i].onMainDestroy();
@ -727,7 +719,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
plugin.onMainDestroy();
}
GodotLib.ondestroy();
GodotLib.ondestroy(this);
super.onDestroy();
@ -737,13 +729,13 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
@Override
public void onPause() {
protected void onPause() {
super.onPause();
activityResumed = false;
if (!godot_initialized) {
if (null != mDownloaderClientStub) {
mDownloaderClientStub.disconnect(getActivity());
mDownloaderClientStub.disconnect(this);
}
return;
}
@ -778,12 +770,12 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
@Override
public void onResume() {
protected void onResume() {
super.onResume();
activityResumed = true;
if (!godot_initialized) {
if (null != mDownloaderClientStub) {
mDownloaderClientStub.connect(getActivity());
mDownloaderClientStub.connect(this);
}
return;
}
@ -796,7 +788,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
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 = getActivity().getWindow();
Window window = getWindow();
window.getDecorView().setSystemUiVisibility(
View.SYSTEM_UI_FLAG_LAYOUT_STABLE |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
@ -816,7 +808,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
public void UiChangeListener() {
final View decorView = getActivity().getWindow().getDecorView();
final View decorView = getWindow().getDecorView();
decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
@Override
public void onSystemUiVisibilityChange(int visibility) {
@ -837,8 +829,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
@Override
public void onSensorChanged(SensorEvent event) {
Display display =
((WindowManager)getActivity().getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int displayRotation = display.getRotation();
float[] adjustedValues = new float[3];
@ -901,6 +892,7 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
*/
@Override
public void onBackPressed() {
boolean shouldQuit = true;
@ -936,12 +928,6 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
}
public final void runOnUiThread(@NonNull Runnable action) {
if (getActivity() != null) {
getActivity().runOnUiThread(action);
}
}
private void forceQuit() {
System.exit(0);
}
@ -1048,16 +1034,17 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
return true;
}
@Override
public boolean onKeyMultiple(final int inKeyCode, int repeatCount, KeyEvent event) {
String s = event.getCharacters();
if (s == null || s.length() == 0)
return false;
return super.onKeyMultiple(inKeyCode, repeatCount, event);
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 false;
if (cnt == 0) return super.onKeyMultiple(inKeyCode, repeatCount, event);
mView.queueEvent(new Runnable() {
// This method will be called on the rendering thread:
public void run() {
@ -1075,15 +1062,15 @@ public class Godot extends Fragment implements SensorEventListener, IDownloaderC
}
public boolean requestPermission(String p_name) {
return PermissionsUtil.requestPermission(p_name, getActivity());
return PermissionsUtil.requestPermission(p_name, this);
}
public boolean requestPermissions() {
return PermissionsUtil.requestManifestPermissions(getActivity());
return PermissionsUtil.requestManifestPermissions(this);
}
public String[] getGrantedPermissions() {
return PermissionsUtil.getGrantedPermissions(getActivity());
return PermissionsUtil.getGrantedPermissions(this);
}
/**

View file

@ -32,7 +32,6 @@ 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;
@ -53,7 +52,7 @@ import java.util.Locale;
public class GodotIO {
AssetManager am;
final Activity activity;
Godot activity;
GodotEditText edit;
MediaPlayer mediaPlayer;
@ -341,7 +340,7 @@ public class GodotIO {
dirs.remove(id);
}
GodotIO(Activity p_activity) {
GodotIO(Godot p_activity) {
am = p_activity.getAssets();
activity = p_activity;

View file

@ -50,13 +50,13 @@ public class GodotLib {
/**
* Invoked on the main thread to initialize Godot native layer.
*/
public static native void initialize(Activity activity, Godot p_instance, Object p_asset_manager, boolean use_apk_expansion);
public static native void initialize(Godot p_instance, Object p_asset_manager, boolean use_apk_expansion);
/**
* Invoked on the main thread to clean up Godot native layer.
* @see androidx.fragment.app.Fragment#onDestroy()
* @see Activity#onDestroy()
*/
public static native void ondestroy();
public static native void ondestroy(Godot p_instance);
/**
* Invoked on the GL thread to complete setup for the Godot native layer logic.
@ -160,14 +160,14 @@ public class GodotLib {
public static native void joyconnectionchanged(int p_device, boolean p_connected, String p_name);
/**
* Invoked when the Android app resumes.
* @see androidx.fragment.app.Fragment#onResume()
* Invoked when the Android activity resumes.
* @see Activity#onResume()
*/
public static native void focusin();
/**
* Invoked when the Android app pauses.
* @see androidx.fragment.app.Fragment#onPause()
* Invoked when the Android activity pauses.
* @see Activity#onPause()
*/
public static native void focusout();

View file

@ -42,7 +42,6 @@ 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;
@ -71,21 +70,20 @@ public class GodotView extends GLSurfaceView {
private static String TAG = GodotView.class.getSimpleName();
private final Godot godot;
private final Godot activity;
private final GodotInputHandler inputHandler;
private final GestureDetector detector;
private final GodotRenderer godotRenderer;
public GodotView(Context context, Godot godot, XRMode xrMode, boolean p_use_gl3,
boolean p_use_32_bits, boolean p_use_debug_opengl) {
super(context);
public GodotView(Godot activity, XRMode xrMode, boolean p_use_gl3, boolean p_use_32_bits, boolean p_use_debug_opengl) {
super(activity);
GLUtils.use_gl3 = p_use_gl3;
GLUtils.use_32 = p_use_32_bits;
GLUtils.use_debug_opengl = p_use_debug_opengl;
this.godot = godot;
this.activity = activity;
this.inputHandler = new GodotInputHandler(this);
this.detector = new GestureDetector(context, new GodotGestureHandler(this));
this.detector = new GestureDetector(activity, new GodotGestureHandler(this));
this.godotRenderer = new GodotRenderer();
init(xrMode, false, 16, 0);
}
@ -99,7 +97,7 @@ public class GodotView extends GLSurfaceView {
public boolean onTouchEvent(MotionEvent event) {
super.onTouchEvent(event);
this.detector.onTouchEvent(event);
return godot.gotTouchEvent(event);
return activity.gotTouchEvent(event);
}
@Override
@ -176,7 +174,7 @@ public class GodotView extends GLSurfaceView {
}
public void onBackPressed() {
godot.onBackPressed();
activity.onBackPressed();
}
@Override

View file

@ -98,7 +98,7 @@ public abstract class GodotPlugin {
*/
@Nullable
protected Activity getActivity() {
return godot.getActivity();
return godot;
}
/**

View file

@ -32,7 +32,6 @@ 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;
@ -123,11 +122,9 @@ public final class GodotPluginRegistry {
private void loadPlugins(Godot godot) {
try {
final Activity activity = godot.getActivity();
ApplicationInfo appInfo = activity
ApplicationInfo appInfo = godot
.getPackageManager()
.getApplicationInfo(activity.getPackageName(),
PackageManager.GET_META_DATA);
.getApplicationInfo(godot.getPackageName(), PackageManager.GET_META_DATA);
Bundle metaData = appInfo.metaData;
if (metaData == null || metaData.isEmpty()) {
return;

View file

@ -30,7 +30,8 @@
package org.godotengine.godot.utils;
import android.app.Activity;
import org.godotengine.godot.Godot;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.util.Log;
@ -45,7 +46,7 @@ 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(Activity p_activity) {
public GodotNetUtils(Godot 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");

View file

@ -30,8 +30,9 @@
package org.godotengine.godot.utils;
import org.godotengine.godot.Godot;
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PermissionInfo;
@ -65,7 +66,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, Activity activity) {
public static boolean requestPermission(String name, Godot activity) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
// Not necessary, asked on install already
return true;
@ -93,7 +94,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(Activity activity) {
public static boolean requestManifestPermissions(Godot activity) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
return true;
}
@ -138,7 +139,7 @@ public final class PermissionsUtil {
* @param activity the caller activity for this method.
* @return granted permissions list
*/
public static String[] getGrantedPermissions(Activity activity) {
public static String[] getGrantedPermissions(Godot activity) {
String[] manifestPermissions;
try {
manifestPermissions = getManifestPermissions(activity);
@ -172,7 +173,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(Activity activity, String permission) {
public static boolean hasManifestPermission(Godot activity, String permission) {
try {
for (String p : getManifestPermissions(activity)) {
if (permission.equals(p))
@ -190,7 +191,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(Activity activity) throws PackageManager.NameNotFoundException {
private static String[] getManifestPermissions(Godot activity) throws PackageManager.NameNotFoundException {
PackageManager packageManager = activity.getPackageManager();
PackageInfo packageInfo = packageManager.getPackageInfo(activity.getPackageName(), PackageManager.GET_PERMISSIONS);
if (packageInfo.requestedPermissions == null)
@ -205,7 +206,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(Activity activity, String permission) throws PackageManager.NameNotFoundException {
private static PermissionInfo getPermissionInfo(Godot activity, String permission) throws PackageManager.NameNotFoundException {
PackageManager packageManager = activity.getPackageManager();
return packageManager.getPermissionInfo(permission, 0);
}

View file

@ -1244,7 +1244,7 @@ JavaClassWrapper::JavaClassWrapper(jobject p_activity) {
JNIEnv *env = ThreadAndroid::get_env();
jclass activityClass = env->FindClass("android/app/Activity");
jclass activityClass = env->FindClass("org/godotengine/godot/Godot");
jmethodID getClassLoader = env->GetMethodID(activityClass, "getClassLoader", "()Ljava/lang/ClassLoader;");
classLoader = env->CallObjectMethod(p_activity, getClassLoader);
classLoader = (jclass)env->NewGlobalRef(classLoader);

View file

@ -120,7 +120,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setVirtualKeyboardHei
}
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject activity, jobject godot_instance, jobject p_asset_manager, jboolean p_use_apk_expansion) {
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject activity, jobject p_asset_manager, jboolean p_use_apk_expansion) {
initialized = true;
@ -128,7 +128,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
env->GetJavaVM(&jvm);
// create our wrapper classes
godot_java = new GodotJavaWrapper(env, activity, godot_instance);
godot_java = new GodotJavaWrapper(env, activity); // our activity is our godot instance is our activity..
godot_io_java = new GodotIOJavaWrapper(env, godot_java->get_member_object("io", "Lorg/godotengine/godot/GodotIO;", env));
ThreadAndroid::make_default(jvm);
@ -153,7 +153,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en
godot_java->on_video_init(env);
}
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz) {
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz, jobject activity) {
// lets cleanup
if (godot_io_java) {
delete godot_io_java;

View file

@ -37,8 +37,8 @@
// These functions can be called from within JAVA and are the means by which our JAVA implementation calls back into our C++ code.
// See java/src/org/godotengine/godot/GodotLib.java for the JAVA side of this (yes that's why we have the long names)
extern "C" {
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject activity, jobject godot_instance, jobject p_asset_manager, jboolean p_use_apk_expansion);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *env, jclass clazz, jobject activity, jobject p_asset_manager, jboolean p_use_apk_expansion);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz, jobject activity);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_resize(JNIEnv *env, jclass clazz, jint width, jint height);
JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jboolean p_32_bits);

View file

@ -37,47 +37,36 @@
// TODO we could probably create a base class for this...
GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_godot_instance) {
GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance) {
godot_instance = p_env->NewGlobalRef(p_godot_instance);
activity = p_env->NewGlobalRef(p_activity);
// get info about our Godot class so we can get pointers and stuff...
godot_class = p_env->FindClass("org/godotengine/godot/Godot");
if (godot_class) {
godot_class = (jclass)p_env->NewGlobalRef(godot_class);
} else {
// this is a pretty serious fail.. bail... pointers will stay 0
return;
}
activity_class = p_env->FindClass("android/app/Activity");
if (activity_class) {
activity_class = (jclass)p_env->NewGlobalRef(activity_class);
cls = p_env->FindClass("org/godotengine/godot/Godot");
if (cls) {
cls = (jclass)p_env->NewGlobalRef(cls);
} else {
// this is a pretty serious fail.. bail... pointers will stay 0
return;
}
// get some Godot method pointers...
_on_video_init = p_env->GetMethodID(godot_class, "onVideoInit", "()V");
_restart = p_env->GetMethodID(godot_class, "restart", "()V");
_finish = p_env->GetMethodID(godot_class, "forceQuit", "()V");
_set_keep_screen_on = p_env->GetMethodID(godot_class, "setKeepScreenOn", "(Z)V");
_alert = p_env->GetMethodID(godot_class, "alert", "(Ljava/lang/String;Ljava/lang/String;)V");
_get_GLES_version_code = p_env->GetMethodID(godot_class, "getGLESVersionCode", "()I");
_get_clipboard = p_env->GetMethodID(godot_class, "getClipboard", "()Ljava/lang/String;");
_set_clipboard = p_env->GetMethodID(godot_class, "setClipboard", "(Ljava/lang/String;)V");
_request_permission = p_env->GetMethodID(godot_class, "requestPermission", "(Ljava/lang/String;)Z");
_request_permissions = p_env->GetMethodID(godot_class, "requestPermissions", "()Z");
_get_granted_permissions = p_env->GetMethodID(godot_class, "getGrantedPermissions", "()[Ljava/lang/String;");
_init_input_devices = p_env->GetMethodID(godot_class, "initInputDevices", "()V");
_get_surface = p_env->GetMethodID(godot_class, "getSurface", "()Landroid/view/Surface;");
_is_activity_resumed = p_env->GetMethodID(godot_class, "isActivityResumed", "()Z");
_vibrate = p_env->GetMethodID(godot_class, "vibrate", "(I)V");
_get_input_fallback_mapping = p_env->GetMethodID(godot_class, "getInputFallbackMapping", "()Ljava/lang/String;");
_on_godot_main_loop_started = p_env->GetMethodID(godot_class, "onGodotMainLoopStarted", "()V");
// get some Activity method pointers...
_get_class_loader = p_env->GetMethodID(activity_class, "getClassLoader", "()Ljava/lang/ClassLoader;");
// get some method pointers...
_on_video_init = p_env->GetMethodID(cls, "onVideoInit", "()V");
_restart = p_env->GetMethodID(cls, "restart", "()V");
_finish = p_env->GetMethodID(cls, "forceQuit", "()V");
_set_keep_screen_on = p_env->GetMethodID(cls, "setKeepScreenOn", "(Z)V");
_alert = p_env->GetMethodID(cls, "alert", "(Ljava/lang/String;Ljava/lang/String;)V");
_get_GLES_version_code = p_env->GetMethodID(cls, "getGLESVersionCode", "()I");
_get_clipboard = p_env->GetMethodID(cls, "getClipboard", "()Ljava/lang/String;");
_set_clipboard = p_env->GetMethodID(cls, "setClipboard", "(Ljava/lang/String;)V");
_request_permission = p_env->GetMethodID(cls, "requestPermission", "(Ljava/lang/String;)Z");
_request_permissions = p_env->GetMethodID(cls, "requestPermissions", "()Z");
_get_granted_permissions = p_env->GetMethodID(cls, "getGrantedPermissions", "()[Ljava/lang/String;");
_init_input_devices = p_env->GetMethodID(cls, "initInputDevices", "()V");
_get_surface = p_env->GetMethodID(cls, "getSurface", "()Landroid/view/Surface;");
_is_activity_resumed = p_env->GetMethodID(cls, "isActivityResumed", "()Z");
_vibrate = p_env->GetMethodID(cls, "vibrate", "(I)V");
_get_input_fallback_mapping = p_env->GetMethodID(cls, "getInputFallbackMapping", "()Ljava/lang/String;");
_on_godot_main_loop_started = p_env->GetMethodID(cls, "onGodotMainLoopStarted", "()V");
}
GodotJavaWrapper::~GodotJavaWrapper() {
@ -85,25 +74,27 @@ GodotJavaWrapper::~GodotJavaWrapper() {
}
jobject GodotJavaWrapper::get_activity() {
return activity;
// our godot instance is our activity
return godot_instance;
}
jobject GodotJavaWrapper::get_member_object(const char *p_name, const char *p_class, JNIEnv *p_env) {
if (godot_class) {
if (cls) {
if (p_env == NULL)
p_env = ThreadAndroid::get_env();
jfieldID fid = p_env->GetStaticFieldID(godot_class, p_name, p_class);
return p_env->GetStaticObjectField(godot_class, fid);
jfieldID fid = p_env->GetStaticFieldID(cls, p_name, p_class);
return p_env->GetStaticObjectField(cls, fid);
} else {
return NULL;
}
}
jobject GodotJavaWrapper::get_class_loader() {
if (_get_class_loader) {
if (cls) {
JNIEnv *env = ThreadAndroid::get_env();
return env->CallObjectMethod(godot_instance, _get_class_loader);
jmethodID getClassLoader = env->GetMethodID(cls, "getClassLoader", "()Ljava/lang/ClassLoader;");
return env->CallObjectMethod(godot_instance, getClassLoader);
} else {
return NULL;
}

View file

@ -43,9 +43,7 @@
class GodotJavaWrapper {
private:
jobject godot_instance;
jobject activity;
jclass godot_class;
jclass activity_class;
jclass cls;
jmethodID _on_video_init = 0;
jmethodID _restart = 0;
@ -64,10 +62,9 @@ private:
jmethodID _vibrate = 0;
jmethodID _get_input_fallback_mapping = 0;
jmethodID _on_godot_main_loop_started = 0;
jmethodID _get_class_loader = 0;
public:
GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_godot_instance);
GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance);
~GodotJavaWrapper();
jobject get_activity();