mirror of
				https://github.com/godotengine/godot.git
				synced 2025-10-31 05:31:01 +00:00 
			
		
		
		
	Merge pull request #42186 from m4gr3d/3.2-android-subview
[3.2] Godot Android Subview Implementation
This commit is contained in:
		
						commit
						fc50d5b38c
					
				
					 16 changed files with 360 additions and 226 deletions
				
			
		|  | @ -30,11 +30,11 @@ | ||||||
| 
 | 
 | ||||||
| package com.godot.game; | package com.godot.game; | ||||||
| 
 | 
 | ||||||
| import org.godotengine.godot.Godot; | import org.godotengine.godot.FullScreenGodotApp; | ||||||
| 
 | 
 | ||||||
| /** | /** | ||||||
|  * Template activity for Godot Android custom builds. |  * Template activity for Godot Android custom builds. | ||||||
|  * Feel free to extend and modify this class for your custom logic. |  * Feel free to extend and modify this class for your custom logic. | ||||||
|  */ |  */ | ||||||
| public class GodotApp extends Godot { | public class GodotApp extends FullScreenGodotApp { | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -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" /> | ||||||
|  | @ -0,0 +1,100 @@ | ||||||
|  | /*************************************************************************/ | ||||||
|  | /*  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.annotation.NonNull; | ||||||
|  | import androidx.annotation.Nullable; | ||||||
|  | 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 { | ||||||
|  | 
 | ||||||
|  | 	@Nullable | ||||||
|  | 	private Godot godotFragment; | ||||||
|  | 
 | ||||||
|  | 	@Override | ||||||
|  | 	public void onCreate(Bundle savedInstanceState) { | ||||||
|  | 		super.onCreate(savedInstanceState); | ||||||
|  | 		setContentView(R.layout.godot_app_layout); | ||||||
|  | 		godotFragment = initGodotInstance(); | ||||||
|  | 		if (godotFragment == null) { | ||||||
|  | 			throw new IllegalStateException("Godot instance must be non-null."); | ||||||
|  | 		} | ||||||
|  | 
 | ||||||
|  | 		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); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	/** | ||||||
|  | 	 * Used to initialize the Godot fragment instance in {@link FullScreenGodotApp#onCreate(Bundle)}. | ||||||
|  | 	 */ | ||||||
|  | 	@NonNull | ||||||
|  | 	protected Godot initGodotInstance() { | ||||||
|  | 		return new Godot(); | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	@Nullable | ||||||
|  | 	protected final Godot getGodotFragment() { | ||||||
|  | 		return godotFragment; | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | @ -30,6 +30,9 @@ | ||||||
| 
 | 
 | ||||||
| package org.godotengine.godot; | 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.input.GodotEditText; | ||||||
| import org.godotengine.godot.plugin.GodotPlugin; | import org.godotengine.godot.plugin.GodotPlugin; | ||||||
| import org.godotengine.godot.plugin.GodotPluginRegistry; | import org.godotengine.godot.plugin.GodotPluginRegistry; | ||||||
|  | @ -70,6 +73,7 @@ import android.os.Vibrator; | ||||||
| import android.provider.Settings.Secure; | import android.provider.Settings.Secure; | ||||||
| import android.view.Display; | import android.view.Display; | ||||||
| import android.view.KeyEvent; | import android.view.KeyEvent; | ||||||
|  | import android.view.LayoutInflater; | ||||||
| import android.view.MotionEvent; | import android.view.MotionEvent; | ||||||
| import android.view.Surface; | import android.view.Surface; | ||||||
| import android.view.View; | import android.view.View; | ||||||
|  | @ -87,7 +91,7 @@ import androidx.annotation.CallSuper; | ||||||
| import androidx.annotation.Keep; | import androidx.annotation.Keep; | ||||||
| import androidx.annotation.NonNull; | import androidx.annotation.NonNull; | ||||||
| import androidx.annotation.Nullable; | import androidx.annotation.Nullable; | ||||||
| import androidx.fragment.app.FragmentActivity; | import androidx.fragment.app.Fragment; | ||||||
| 
 | 
 | ||||||
| import com.google.android.vending.expansion.downloader.DownloadProgressInfo; | import com.google.android.vending.expansion.downloader.DownloadProgressInfo; | ||||||
| import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller; | import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller; | ||||||
|  | @ -109,7 +113,7 @@ import java.util.Locale; | ||||||
| 
 | 
 | ||||||
| import javax.microedition.khronos.opengles.GL10; | import javax.microedition.khronos.opengles.GL10; | ||||||
| 
 | 
 | ||||||
| public abstract class Godot extends FragmentActivity implements SensorEventListener, IDownloaderClient { | public class Godot extends Fragment implements SensorEventListener, IDownloaderClient { | ||||||
| 
 | 
 | ||||||
| 	static final int MAX_SINGLETONS = 64; | 	static final int MAX_SINGLETONS = 64; | ||||||
| 	private IStub mDownloaderClientStub; | 	private IStub mDownloaderClientStub; | ||||||
|  | @ -142,7 +146,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 
 | 
 | ||||||
| 	static private Intent mCurrentIntent; | 	static private Intent mCurrentIntent; | ||||||
| 
 | 
 | ||||||
| 	@Override |  | ||||||
| 	public void onNewIntent(Intent intent) { | 	public void onNewIntent(Intent intent) { | ||||||
| 		mCurrentIntent = intent; | 		mCurrentIntent = intent; | ||||||
| 	} | 	} | ||||||
|  | @ -244,6 +247,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 	private String[] command_line; | 	private String[] command_line; | ||||||
| 	private boolean use_apk_expansion; | 	private boolean use_apk_expansion; | ||||||
| 
 | 
 | ||||||
|  | 	private ViewGroup containerLayout; | ||||||
| 	public GodotView mView; | 	public GodotView mView; | ||||||
| 	private boolean godot_initialized = false; | 	private boolean godot_initialized = false; | ||||||
| 
 | 
 | ||||||
|  | @ -265,7 +269,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 	public ResultCallback result_callback; | 	public ResultCallback result_callback; | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	protected void onActivityResult(int requestCode, int resultCode, Intent data) { | 	public void onActivityResult(int requestCode, int resultCode, Intent data) { | ||||||
| 		if (result_callback != null) { | 		if (result_callback != null) { | ||||||
| 			result_callback.callback(requestCode, resultCode, data); | 			result_callback.callback(requestCode, resultCode, data); | ||||||
| 			result_callback = null; | 			result_callback = null; | ||||||
|  | @ -311,19 +315,19 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 	private void onVideoInit() { | 	private void onVideoInit() { | ||||||
| 		boolean use_gl3 = getGLESVersionCode() >= 0x00030000; | 		boolean use_gl3 = getGLESVersionCode() >= 0x00030000; | ||||||
| 
 | 
 | ||||||
| 		final FrameLayout layout = new FrameLayout(this); | 		final Activity activity = getActivity(); | ||||||
| 		layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); | 		containerLayout = new FrameLayout(activity); | ||||||
| 		setContentView(layout); | 		containerLayout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); | ||||||
| 
 | 
 | ||||||
| 		// GodotEditText layout | 		// GodotEditText layout | ||||||
| 		GodotEditText edittext = new GodotEditText(this); | 		GodotEditText edittext = new GodotEditText(activity); | ||||||
| 		edittext.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, | 		edittext.setLayoutParams(new ViewGroup.LayoutParams(LayoutParams.MATCH_PARENT, | ||||||
| 				(int)getResources().getDimension(R.dimen.text_edit_height))); | 				(int)getResources().getDimension(R.dimen.text_edit_height))); | ||||||
| 		// ...add to FrameLayout | 		// ...add to FrameLayout | ||||||
| 		layout.addView(edittext); | 		containerLayout.addView(edittext); | ||||||
| 
 | 
 | ||||||
| 		mView = new GodotView(this, xrMode, use_gl3, use_32_bits, use_debug_opengl); | 		mView = new GodotView(activity, this, xrMode, use_gl3, use_32_bits, use_debug_opengl); | ||||||
| 		layout.addView(mView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); | 		containerLayout.addView(mView, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)); | ||||||
| 		edittext.setView(mView); | 		edittext.setView(mView); | ||||||
| 		io.setEdit(edittext); | 		io.setEdit(edittext); | ||||||
| 
 | 
 | ||||||
|  | @ -331,7 +335,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 			@Override | 			@Override | ||||||
| 			public void onGlobalLayout() { | 			public void onGlobalLayout() { | ||||||
| 				Point fullSize = new Point(); | 				Point fullSize = new Point(); | ||||||
| 				getWindowManager().getDefaultDisplay().getSize(fullSize); | 				activity.getWindowManager().getDefaultDisplay().getSize(fullSize); | ||||||
| 				Rect gameSize = new Rect(); | 				Rect gameSize = new Rect(); | ||||||
| 				mView.getWindowVisibleDisplayFrame(gameSize); | 				mView.getWindowVisibleDisplayFrame(gameSize); | ||||||
| 
 | 
 | ||||||
|  | @ -359,9 +363,9 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 					public void run() { | 					public void run() { | ||||||
| 						// Include the non-null views returned in the Godot view hierarchy. | 						// Include the non-null views returned in the Godot view hierarchy. | ||||||
| 						for (int i = 0; i < singleton_count; i++) { | 						for (int i = 0; i < singleton_count; i++) { | ||||||
| 							View view = singletons[i].onMainCreateView(Godot.this); | 							View view = singletons[i].onMainCreateView(activity); | ||||||
| 							if (view != null) { | 							if (view != null) { | ||||||
| 								layout.addView(view); | 								containerLayout.addView(view); | ||||||
| 							} | 							} | ||||||
| 						} | 						} | ||||||
| 					} | 					} | ||||||
|  | @ -371,9 +375,9 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 
 | 
 | ||||||
| 		// Include the returned non-null views in the Godot view hierarchy. | 		// Include the returned non-null views in the Godot view hierarchy. | ||||||
| 		for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) { | 		for (GodotPlugin plugin : pluginRegistry.getAllPlugins()) { | ||||||
| 			View pluginView = plugin.onMainCreate(this); | 			View pluginView = plugin.onMainCreate(activity); | ||||||
| 			if (pluginView != null) { | 			if (pluginView != null) { | ||||||
| 				layout.addView(pluginView); | 				containerLayout.addView(pluginView); | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  | @ -383,9 +387,9 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 			@Override | 			@Override | ||||||
| 			public void run() { | 			public void run() { | ||||||
| 				if (p_enabled) { | 				if (p_enabled) { | ||||||
| 					getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); | 					getActivity().getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); | ||||||
| 				} else { | 				} else { | ||||||
| 					getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); | 					getActivity().getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
|  | @ -399,7 +403,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 	@Keep | 	@Keep | ||||||
| 	private void vibrate(int durationMs) { | 	private void vibrate(int durationMs) { | ||||||
| 		if (requestPermission("VIBRATE")) { | 		if (requestPermission("VIBRATE")) { | ||||||
| 			Vibrator v = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE); | 			Vibrator v = (Vibrator)getContext().getSystemService(Context.VIBRATOR_SERVICE); | ||||||
| 			if (v != null) { | 			if (v != null) { | ||||||
| 				if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | 				if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { | ||||||
| 					v.vibrate(VibrationEffect.createOneShot(durationMs, VibrationEffect.DEFAULT_AMPLITUDE)); | 					v.vibrate(VibrationEffect.createOneShot(durationMs, VibrationEffect.DEFAULT_AMPLITUDE)); | ||||||
|  | @ -423,13 +427,16 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 		// Using instrumentation is a way of making the whole app process restart, because Android | 		// 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. | 		// will kill any process of the same package which was already running. | ||||||
| 		// | 		// | ||||||
|  | 		final Activity activity = getActivity(); | ||||||
|  | 		if (activity != null) { | ||||||
| 			Bundle args = new Bundle(); | 			Bundle args = new Bundle(); | ||||||
| 			args.putParcelable("intent", mCurrentIntent); | 			args.putParcelable("intent", mCurrentIntent); | ||||||
| 		startInstrumentation(new ComponentName(this, GodotInstrumentation.class), null, args); | 			activity.startInstrumentation(new ComponentName(activity, GodotInstrumentation.class), null, args); | ||||||
|  | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void alert(final String message, final String title) { | 	public void alert(final String message, final String title) { | ||||||
| 		final Activity activity = this; | 		final Activity activity = getActivity(); | ||||||
| 		runOnUiThread(new Runnable() { | 		runOnUiThread(new Runnable() { | ||||||
| 			@Override | 			@Override | ||||||
| 			public void run() { | 			public void run() { | ||||||
|  | @ -449,7 +456,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public int getGLESVersionCode() { | 	public int getGLESVersionCode() { | ||||||
| 		ActivityManager am = (ActivityManager)this.getSystemService(Context.ACTIVITY_SERVICE); | 		ActivityManager am = (ActivityManager)getContext().getSystemService(Context.ACTIVITY_SERVICE); | ||||||
| 		ConfigurationInfo deviceInfo = am.getDeviceConfigurationInfo(); | 		ConfigurationInfo deviceInfo = am.getDeviceConfigurationInfo(); | ||||||
| 		return deviceInfo.reqGlEsVersion; | 		return deviceInfo.reqGlEsVersion; | ||||||
| 	} | 	} | ||||||
|  | @ -458,7 +465,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 	protected String[] getCommandLine() { | 	protected String[] getCommandLine() { | ||||||
| 		InputStream is; | 		InputStream is; | ||||||
| 		try { | 		try { | ||||||
| 			is = getAssets().open("_cl_"); | 			is = getActivity().getAssets().open("_cl_"); | ||||||
| 			byte[] len = new byte[4]; | 			byte[] len = new byte[4]; | ||||||
| 			int r = is.read(len); | 			int r = is.read(len); | ||||||
| 			if (r < 4) { | 			if (r < 4) { | ||||||
|  | @ -538,11 +545,12 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 			command_line = new_cmdline; | 			command_line = new_cmdline; | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		io = new GodotIO(this); | 		final Activity activity = getActivity(); | ||||||
| 		io.unique_id = Secure.getString(getContentResolver(), Secure.ANDROID_ID); | 		io = new GodotIO(activity); | ||||||
|  | 		io.unique_id = Secure.getString(activity.getContentResolver(), Secure.ANDROID_ID); | ||||||
| 		GodotLib.io = io; | 		GodotLib.io = io; | ||||||
| 		netUtils = new GodotNetUtils(this); | 		netUtils = new GodotNetUtils(activity); | ||||||
| 		mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); | 		mSensorManager = (SensorManager)activity.getSystemService(Context.SENSOR_SERVICE); | ||||||
| 		mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); | 		mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); | ||||||
| 		mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME); | 		mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_GAME); | ||||||
| 		mGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY); | 		mGravity = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY); | ||||||
|  | @ -552,7 +560,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 		mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE); | 		mGyroscope = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE); | ||||||
| 		mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME); | 		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; | 		result_callback = null; | ||||||
| 
 | 
 | ||||||
|  | @ -566,16 +574,14 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	protected void onCreate(Bundle icicle) { | 	public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle icicle) { | ||||||
| 
 | 		final Activity activity = getActivity(); | ||||||
| 		super.onCreate(icicle); | 		Window window = activity.getWindow(); | ||||||
| 		Window window = getWindow(); |  | ||||||
| 		window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); | 		window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON); | ||||||
| 		mClipboard = (ClipboardManager)getSystemService(Context.CLIPBOARD_SERVICE); | 		mClipboard = (ClipboardManager)activity.getSystemService(Context.CLIPBOARD_SERVICE); | ||||||
| 		pluginRegistry = GodotPluginRegistry.initializePluginRegistry(this); | 		pluginRegistry = GodotPluginRegistry.initializePluginRegistry(this); | ||||||
| 
 | 
 | ||||||
| 		//check for apk expansion API | 		//check for apk expansion API | ||||||
| 		if (true) { |  | ||||||
| 		boolean md5mismatch = false; | 		boolean md5mismatch = false; | ||||||
| 		command_line = getCommandLine(); | 		command_line = getCommandLine(); | ||||||
| 		String main_pack_md5 = null; | 		String main_pack_md5 = null; | ||||||
|  | @ -614,7 +620,8 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 				i++; | 				i++; | ||||||
| 			} else if (has_extra && command_line[i].equals("--apk_expansion_key")) { | 			} else if (has_extra && command_line[i].equals("--apk_expansion_key")) { | ||||||
| 				main_pack_key = command_line[i + 1]; | 				main_pack_key = command_line[i + 1]; | ||||||
| 					SharedPreferences prefs = getSharedPreferences("app_data_keys", MODE_PRIVATE); | 				SharedPreferences prefs = activity.getSharedPreferences("app_data_keys", | ||||||
|  | 						MODE_PRIVATE); | ||||||
| 				Editor editor = prefs.edit(); | 				Editor editor = prefs.edit(); | ||||||
| 				editor.putString("store_public_key", main_pack_key); | 				editor.putString("store_public_key", main_pack_key); | ||||||
| 
 | 
 | ||||||
|  | @ -639,8 +646,8 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 
 | 
 | ||||||
| 			// Build the full path to the app's expansion files | 			// Build the full path to the app's expansion files | ||||||
| 			try { | 			try { | ||||||
| 					expansion_pack_path = Helpers.getSaveFilePath(getApplicationContext()); | 				expansion_pack_path = Helpers.getSaveFilePath(getContext()); | ||||||
| 					expansion_pack_path += "/main." + getPackageManager().getPackageInfo(getPackageName(), 0).versionCode + "." + this.getPackageName() + ".obb"; | 				expansion_pack_path += "/main." + activity.getPackageManager().getPackageInfo(activity.getPackageName(), 0).versionCode + "." + activity.getPackageName() + ".obb"; | ||||||
| 			} catch (Exception e) { | 			} catch (Exception e) { | ||||||
| 				e.printStackTrace(); | 				e.printStackTrace(); | ||||||
| 			} | 			} | ||||||
|  | @ -663,17 +670,17 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 
 | 
 | ||||||
| 			if (!pack_valid) { | 			if (!pack_valid) { | ||||||
| 
 | 
 | ||||||
| 					Intent notifierIntent = new Intent(this, this.getClass()); | 				Intent notifierIntent = new Intent(activity, activity.getClass()); | ||||||
| 				notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | | 				notifierIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | | ||||||
| 										Intent.FLAG_ACTIVITY_CLEAR_TOP); | 										Intent.FLAG_ACTIVITY_CLEAR_TOP); | ||||||
| 
 | 
 | ||||||
| 					PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, | 				PendingIntent pendingIntent = PendingIntent.getActivity(activity, 0, | ||||||
| 						notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT); | 						notifierIntent, PendingIntent.FLAG_UPDATE_CURRENT); | ||||||
| 
 | 
 | ||||||
| 				int startResult; | 				int startResult; | ||||||
| 				try { | 				try { | ||||||
| 					startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired( | 					startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired( | ||||||
| 								getApplicationContext(), | 							getContext(), | ||||||
| 							pendingIntent, | 							pendingIntent, | ||||||
| 							GodotDownloaderService.class); | 							GodotDownloaderService.class); | ||||||
| 
 | 
 | ||||||
|  | @ -683,34 +690,35 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 						mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this, | 						mDownloaderClientStub = DownloaderClientMarshaller.CreateStub(this, | ||||||
| 								GodotDownloaderService.class); | 								GodotDownloaderService.class); | ||||||
| 
 | 
 | ||||||
| 							setContentView(R.layout.downloading_expansion); | 						View downloadingExpansionView = | ||||||
| 							mPB = (ProgressBar)findViewById(R.id.progressBar); | 								inflater.inflate(R.layout.downloading_expansion, container, false); | ||||||
| 							mStatusText = (TextView)findViewById(R.id.statusText); | 						mPB = (ProgressBar)downloadingExpansionView.findViewById(R.id.progressBar); | ||||||
| 							mProgressFraction = (TextView)findViewById(R.id.progressAsFraction); | 						mStatusText = (TextView)downloadingExpansionView.findViewById(R.id.statusText); | ||||||
| 							mProgressPercent = (TextView)findViewById(R.id.progressAsPercentage); | 						mProgressFraction = (TextView)downloadingExpansionView.findViewById(R.id.progressAsFraction); | ||||||
| 							mAverageSpeed = (TextView)findViewById(R.id.progressAverageSpeed); | 						mProgressPercent = (TextView)downloadingExpansionView.findViewById(R.id.progressAsPercentage); | ||||||
| 							mTimeRemaining = (TextView)findViewById(R.id.progressTimeRemaining); | 						mAverageSpeed = (TextView)downloadingExpansionView.findViewById(R.id.progressAverageSpeed); | ||||||
| 							mDashboard = findViewById(R.id.downloaderDashboard); | 						mTimeRemaining = (TextView)downloadingExpansionView.findViewById(R.id.progressTimeRemaining); | ||||||
| 							mCellMessage = findViewById(R.id.approveCellular); | 						mDashboard = downloadingExpansionView.findViewById(R.id.downloaderDashboard); | ||||||
| 							mPauseButton = (Button)findViewById(R.id.pauseButton); | 						mCellMessage = downloadingExpansionView.findViewById(R.id.approveCellular); | ||||||
| 							mWiFiSettingsButton = (Button)findViewById(R.id.wifiSettingsButton); | 						mPauseButton = (Button)downloadingExpansionView.findViewById(R.id.pauseButton); | ||||||
|  | 						mWiFiSettingsButton = (Button)downloadingExpansionView.findViewById(R.id.wifiSettingsButton); | ||||||
| 
 | 
 | ||||||
| 							return; | 						return downloadingExpansionView; | ||||||
| 					} | 					} | ||||||
| 				} catch (NameNotFoundException e) { | 				} catch (NameNotFoundException e) { | ||||||
| 					// TODO Auto-generated catch block | 					// TODO Auto-generated catch block | ||||||
| 				} | 				} | ||||||
| 			} | 			} | ||||||
| 		} | 		} | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		mCurrentIntent = getIntent(); | 		mCurrentIntent = activity.getIntent(); | ||||||
| 
 | 
 | ||||||
| 		initializeGodot(); | 		initializeGodot(); | ||||||
|  | 		return containerLayout; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	protected void onDestroy() { | 	public void onDestroy() { | ||||||
| 
 | 
 | ||||||
| 		for (int i = 0; i < singleton_count; i++) { | 		for (int i = 0; i < singleton_count; i++) { | ||||||
| 			singletons[i].onMainDestroy(); | 			singletons[i].onMainDestroy(); | ||||||
|  | @ -719,7 +727,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 			plugin.onMainDestroy(); | 			plugin.onMainDestroy(); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		GodotLib.ondestroy(this); | 		GodotLib.ondestroy(); | ||||||
| 
 | 
 | ||||||
| 		super.onDestroy(); | 		super.onDestroy(); | ||||||
| 
 | 
 | ||||||
|  | @ -729,13 +737,13 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	protected void onPause() { | 	public void onPause() { | ||||||
| 		super.onPause(); | 		super.onPause(); | ||||||
| 		activityResumed = false; | 		activityResumed = false; | ||||||
| 
 | 
 | ||||||
| 		if (!godot_initialized) { | 		if (!godot_initialized) { | ||||||
| 			if (null != mDownloaderClientStub) { | 			if (null != mDownloaderClientStub) { | ||||||
| 				mDownloaderClientStub.disconnect(this); | 				mDownloaderClientStub.disconnect(getActivity()); | ||||||
| 			} | 			} | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  | @ -770,12 +778,12 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	protected void onResume() { | 	public void onResume() { | ||||||
| 		super.onResume(); | 		super.onResume(); | ||||||
| 		activityResumed = true; | 		activityResumed = true; | ||||||
| 		if (!godot_initialized) { | 		if (!godot_initialized) { | ||||||
| 			if (null != mDownloaderClientStub) { | 			if (null != mDownloaderClientStub) { | ||||||
| 				mDownloaderClientStub.connect(this); | 				mDownloaderClientStub.connect(getActivity()); | ||||||
| 			} | 			} | ||||||
| 			return; | 			return; | ||||||
| 		} | 		} | ||||||
|  | @ -788,7 +796,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 		mSensorManager.registerListener(this, mGyroscope, SensorManager.SENSOR_DELAY_GAME); | 		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+ | 		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( | 			window.getDecorView().setSystemUiVisibility( | ||||||
| 					View.SYSTEM_UI_FLAG_LAYOUT_STABLE | | 					View.SYSTEM_UI_FLAG_LAYOUT_STABLE | | ||||||
| 					View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | | 					View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION | | ||||||
|  | @ -808,7 +816,7 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void UiChangeListener() { | 	public void UiChangeListener() { | ||||||
| 		final View decorView = getWindow().getDecorView(); | 		final View decorView = getActivity().getWindow().getDecorView(); | ||||||
| 		decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() { | 		decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() { | ||||||
| 			@Override | 			@Override | ||||||
| 			public void onSystemUiVisibilityChange(int visibility) { | 			public void onSystemUiVisibilityChange(int visibility) { | ||||||
|  | @ -829,7 +837,8 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
| 	public void onSensorChanged(SensorEvent event) { | 	public void onSensorChanged(SensorEvent event) { | ||||||
| 		Display display = ((WindowManager)getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); | 		Display display = | ||||||
|  | 				((WindowManager)getActivity().getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); | ||||||
| 		int displayRotation = display.getRotation(); | 		int displayRotation = display.getRotation(); | ||||||
| 
 | 
 | ||||||
| 		float[] adjustedValues = new float[3]; | 		float[] adjustedValues = new float[3]; | ||||||
|  | @ -892,7 +901,6 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 	} | 	} | ||||||
| 	*/ | 	*/ | ||||||
| 
 | 
 | ||||||
| 	@Override |  | ||||||
| 	public void onBackPressed() { | 	public void onBackPressed() { | ||||||
| 		boolean shouldQuit = true; | 		boolean shouldQuit = true; | ||||||
| 
 | 
 | ||||||
|  | @ -928,6 +936,12 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	public final void runOnUiThread(@NonNull Runnable action) { | ||||||
|  | 		if (getActivity() != null) { | ||||||
|  | 			getActivity().runOnUiThread(action); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	private void forceQuit() { | 	private void forceQuit() { | ||||||
| 		System.exit(0); | 		System.exit(0); | ||||||
| 	} | 	} | ||||||
|  | @ -1034,17 +1048,16 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 		return true; | 		return true; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override |  | ||||||
| 	public boolean onKeyMultiple(final int inKeyCode, int repeatCount, KeyEvent event) { | 	public boolean onKeyMultiple(final int inKeyCode, int repeatCount, KeyEvent event) { | ||||||
| 		String s = event.getCharacters(); | 		String s = event.getCharacters(); | ||||||
| 		if (s == null || s.length() == 0) | 		if (s == null || s.length() == 0) | ||||||
| 			return super.onKeyMultiple(inKeyCode, repeatCount, event); | 			return false; | ||||||
| 
 | 
 | ||||||
| 		final char[] cc = s.toCharArray(); | 		final char[] cc = s.toCharArray(); | ||||||
| 		int cnt = 0; | 		int cnt = 0; | ||||||
| 		for (int i = cc.length; --i >= 0; cnt += cc[i] != 0 ? 1 : 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; | ||||||
| 		mView.queueEvent(new Runnable() { | 		mView.queueEvent(new Runnable() { | ||||||
| 			// This method will be called on the rendering thread: | 			// This method will be called on the rendering thread: | ||||||
| 			public void run() { | 			public void run() { | ||||||
|  | @ -1062,15 +1075,15 @@ public abstract class Godot extends FragmentActivity implements SensorEventListe | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public boolean requestPermission(String p_name) { | 	public boolean requestPermission(String p_name) { | ||||||
| 		return PermissionsUtil.requestPermission(p_name, this); | 		return PermissionsUtil.requestPermission(p_name, getActivity()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public boolean requestPermissions() { | 	public boolean requestPermissions() { | ||||||
| 		return PermissionsUtil.requestManifestPermissions(this); | 		return PermissionsUtil.requestManifestPermissions(getActivity()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public String[] getGrantedPermissions() { | 	public String[] getGrantedPermissions() { | ||||||
| 		return PermissionsUtil.getGrantedPermissions(this); | 		return PermissionsUtil.getGrantedPermissions(getActivity()); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
|  |  | ||||||
|  | @ -32,6 +32,7 @@ package org.godotengine.godot; | ||||||
| 
 | 
 | ||||||
| import org.godotengine.godot.input.*; | import org.godotengine.godot.input.*; | ||||||
| 
 | 
 | ||||||
|  | import android.app.Activity; | ||||||
| import android.content.*; | import android.content.*; | ||||||
| import android.content.Intent; | import android.content.Intent; | ||||||
| import android.content.pm.ActivityInfo; | import android.content.pm.ActivityInfo; | ||||||
|  | @ -52,7 +53,7 @@ import java.util.Locale; | ||||||
| public class GodotIO { | public class GodotIO { | ||||||
| 
 | 
 | ||||||
| 	AssetManager am; | 	AssetManager am; | ||||||
| 	Godot activity; | 	final Activity activity; | ||||||
| 	GodotEditText edit; | 	GodotEditText edit; | ||||||
| 
 | 
 | ||||||
| 	MediaPlayer mediaPlayer; | 	MediaPlayer mediaPlayer; | ||||||
|  | @ -340,7 +341,7 @@ public class GodotIO { | ||||||
| 		dirs.remove(id); | 		dirs.remove(id); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	GodotIO(Godot p_activity) { | 	GodotIO(Activity p_activity) { | ||||||
| 
 | 
 | ||||||
| 		am = p_activity.getAssets(); | 		am = p_activity.getAssets(); | ||||||
| 		activity = p_activity; | 		activity = p_activity; | ||||||
|  |  | ||||||
|  | @ -50,13 +50,13 @@ public class GodotLib { | ||||||
| 	/** | 	/** | ||||||
| 	 * Invoked on the main thread to initialize Godot native layer. | 	 * 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. | 	 * 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. | 	 * 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); | 	public static native void joyconnectionchanged(int p_device, boolean p_connected, String p_name); | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Invoked when the Android activity resumes. | 	 * Invoked when the Android app resumes. | ||||||
| 	 * @see Activity#onResume() | 	 * @see androidx.fragment.app.Fragment#onResume() | ||||||
| 	 */ | 	 */ | ||||||
| 	public static native void focusin(); | 	public static native void focusin(); | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
| 	 * Invoked when the Android activity pauses. | 	 * Invoked when the Android app pauses. | ||||||
| 	 * @see Activity#onPause() | 	 * @see androidx.fragment.app.Fragment#onPause() | ||||||
| 	 */ | 	 */ | ||||||
| 	public static native void focusout(); | 	public static native void focusout(); | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -42,6 +42,7 @@ import org.godotengine.godot.xr.regular.RegularContextFactory; | ||||||
| import org.godotengine.godot.xr.regular.RegularFallbackConfigChooser; | import org.godotengine.godot.xr.regular.RegularFallbackConfigChooser; | ||||||
| 
 | 
 | ||||||
| import android.annotation.SuppressLint; | import android.annotation.SuppressLint; | ||||||
|  | import android.content.Context; | ||||||
| import android.graphics.PixelFormat; | import android.graphics.PixelFormat; | ||||||
| import android.opengl.GLSurfaceView; | import android.opengl.GLSurfaceView; | ||||||
| import android.view.GestureDetector; | import android.view.GestureDetector; | ||||||
|  | @ -70,20 +71,21 @@ public class GodotView extends GLSurfaceView { | ||||||
| 
 | 
 | ||||||
| 	private static String TAG = GodotView.class.getSimpleName(); | 	private static String TAG = GodotView.class.getSimpleName(); | ||||||
| 
 | 
 | ||||||
| 	private final Godot activity; | 	private final Godot godot; | ||||||
| 	private final GodotInputHandler inputHandler; | 	private final GodotInputHandler inputHandler; | ||||||
| 	private final GestureDetector detector; | 	private final GestureDetector detector; | ||||||
| 	private final GodotRenderer godotRenderer; | 	private final GodotRenderer godotRenderer; | ||||||
| 
 | 
 | ||||||
| 	public GodotView(Godot activity, XRMode xrMode, boolean p_use_gl3, boolean p_use_32_bits, boolean p_use_debug_opengl) { | 	public GodotView(Context context, Godot godot, XRMode xrMode, boolean p_use_gl3, | ||||||
| 		super(activity); | 			boolean p_use_32_bits, boolean p_use_debug_opengl) { | ||||||
|  | 		super(context); | ||||||
| 		GLUtils.use_gl3 = p_use_gl3; | 		GLUtils.use_gl3 = p_use_gl3; | ||||||
| 		GLUtils.use_32 = p_use_32_bits; | 		GLUtils.use_32 = p_use_32_bits; | ||||||
| 		GLUtils.use_debug_opengl = p_use_debug_opengl; | 		GLUtils.use_debug_opengl = p_use_debug_opengl; | ||||||
| 
 | 
 | ||||||
| 		this.activity = activity; | 		this.godot = godot; | ||||||
| 		this.inputHandler = new GodotInputHandler(this); | 		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(); | 		this.godotRenderer = new GodotRenderer(); | ||||||
| 		init(xrMode, false, 16, 0); | 		init(xrMode, false, 16, 0); | ||||||
| 	} | 	} | ||||||
|  | @ -97,7 +99,7 @@ public class GodotView extends GLSurfaceView { | ||||||
| 	public boolean onTouchEvent(MotionEvent event) { | 	public boolean onTouchEvent(MotionEvent event) { | ||||||
| 		super.onTouchEvent(event); | 		super.onTouchEvent(event); | ||||||
| 		this.detector.onTouchEvent(event); | 		this.detector.onTouchEvent(event); | ||||||
| 		return activity.gotTouchEvent(event); | 		return godot.gotTouchEvent(event); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
|  | @ -174,7 +176,7 @@ public class GodotView extends GLSurfaceView { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	public void onBackPressed() { | 	public void onBackPressed() { | ||||||
| 		activity.onBackPressed(); | 		godot.onBackPressed(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	@Override | 	@Override | ||||||
|  |  | ||||||
|  | @ -98,7 +98,7 @@ public abstract class GodotPlugin { | ||||||
| 	 */ | 	 */ | ||||||
| 	@Nullable | 	@Nullable | ||||||
| 	protected Activity getActivity() { | 	protected Activity getActivity() { | ||||||
| 		return godot; | 		return godot.getActivity(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	/** | 	/** | ||||||
|  |  | ||||||
|  | @ -32,6 +32,7 @@ package org.godotengine.godot.plugin; | ||||||
| 
 | 
 | ||||||
| import org.godotengine.godot.Godot; | import org.godotengine.godot.Godot; | ||||||
| 
 | 
 | ||||||
|  | import android.app.Activity; | ||||||
| import android.content.pm.ApplicationInfo; | import android.content.pm.ApplicationInfo; | ||||||
| import android.content.pm.PackageManager; | import android.content.pm.PackageManager; | ||||||
| import android.os.Bundle; | import android.os.Bundle; | ||||||
|  | @ -122,9 +123,11 @@ public final class GodotPluginRegistry { | ||||||
| 
 | 
 | ||||||
| 	private void loadPlugins(Godot godot) { | 	private void loadPlugins(Godot godot) { | ||||||
| 		try { | 		try { | ||||||
| 			ApplicationInfo appInfo = godot | 			final Activity activity = godot.getActivity(); | ||||||
|  | 			ApplicationInfo appInfo = activity | ||||||
| 											  .getPackageManager() | 											  .getPackageManager() | ||||||
| 											  .getApplicationInfo(godot.getPackageName(), PackageManager.GET_META_DATA); | 											  .getApplicationInfo(activity.getPackageName(), | ||||||
|  | 													  PackageManager.GET_META_DATA); | ||||||
| 			Bundle metaData = appInfo.metaData; | 			Bundle metaData = appInfo.metaData; | ||||||
| 			if (metaData == null || metaData.isEmpty()) { | 			if (metaData == null || metaData.isEmpty()) { | ||||||
| 				return; | 				return; | ||||||
|  |  | ||||||
|  | @ -30,8 +30,7 @@ | ||||||
| 
 | 
 | ||||||
| package org.godotengine.godot.utils; | package org.godotengine.godot.utils; | ||||||
| 
 | 
 | ||||||
| import org.godotengine.godot.Godot; | import android.app.Activity; | ||||||
| 
 |  | ||||||
| import android.content.Context; | import android.content.Context; | ||||||
| import android.net.wifi.WifiManager; | import android.net.wifi.WifiManager; | ||||||
| import android.util.Log; | import android.util.Log; | ||||||
|  | @ -46,7 +45,7 @@ public class GodotNetUtils { | ||||||
| 	/* A single, reference counted, multicast lock, or null if permission CHANGE_WIFI_MULTICAST_STATE is missing */ | 	/* A single, reference counted, multicast lock, or null if permission CHANGE_WIFI_MULTICAST_STATE is missing */ | ||||||
| 	private WifiManager.MulticastLock multicastLock; | 	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")) { | 		if (PermissionsUtil.hasManifestPermission(p_activity, "android.permission.CHANGE_WIFI_MULTICAST_STATE")) { | ||||||
| 			WifiManager wifi = (WifiManager)p_activity.getApplicationContext().getSystemService(Context.WIFI_SERVICE); | 			WifiManager wifi = (WifiManager)p_activity.getApplicationContext().getSystemService(Context.WIFI_SERVICE); | ||||||
| 			multicastLock = wifi.createMulticastLock("GodotMulticastLock"); | 			multicastLock = wifi.createMulticastLock("GodotMulticastLock"); | ||||||
|  |  | ||||||
|  | @ -30,9 +30,8 @@ | ||||||
| 
 | 
 | ||||||
| package org.godotengine.godot.utils; | package org.godotengine.godot.utils; | ||||||
| 
 | 
 | ||||||
| import org.godotengine.godot.Godot; |  | ||||||
| 
 |  | ||||||
| import android.Manifest; | import android.Manifest; | ||||||
|  | import android.app.Activity; | ||||||
| import android.content.pm.PackageInfo; | import android.content.pm.PackageInfo; | ||||||
| import android.content.pm.PackageManager; | import android.content.pm.PackageManager; | ||||||
| import android.content.pm.PermissionInfo; | import android.content.pm.PermissionInfo; | ||||||
|  | @ -66,7 +65,7 @@ public final class PermissionsUtil { | ||||||
| 	 * @param activity the caller activity for this method. | 	 * @param activity the caller activity for this method. | ||||||
| 	 * @return true/false. "true" if permission was granted otherwise returns "false". | 	 * @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) { | 		if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { | ||||||
| 			// Not necessary, asked on install already | 			// Not necessary, asked on install already | ||||||
| 			return true; | 			return true; | ||||||
|  | @ -94,7 +93,7 @@ public final class PermissionsUtil { | ||||||
| 	 * @param activity the caller activity for this method. | 	 * @param activity the caller activity for this method. | ||||||
| 	 * @return true/false. "true" if all permissions were granted otherwise returns "false". | 	 * @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) { | 		if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { | ||||||
| 			return true; | 			return true; | ||||||
| 		} | 		} | ||||||
|  | @ -139,7 +138,7 @@ public final class PermissionsUtil { | ||||||
| 	 * @param activity the caller activity for this method. | 	 * @param activity the caller activity for this method. | ||||||
| 	 * @return granted permissions list | 	 * @return granted permissions list | ||||||
| 	 */ | 	 */ | ||||||
| 	public static String[] getGrantedPermissions(Godot activity) { | 	public static String[] getGrantedPermissions(Activity activity) { | ||||||
| 		String[] manifestPermissions; | 		String[] manifestPermissions; | ||||||
| 		try { | 		try { | ||||||
| 			manifestPermissions = getManifestPermissions(activity); | 			manifestPermissions = getManifestPermissions(activity); | ||||||
|  | @ -173,7 +172,7 @@ public final class PermissionsUtil { | ||||||
| 	 * @param permission the permession to look for in the manifest file. | 	 * @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. | 	 * @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 { | 		try { | ||||||
| 			for (String p : getManifestPermissions(activity)) { | 			for (String p : getManifestPermissions(activity)) { | ||||||
| 				if (permission.equals(p)) | 				if (permission.equals(p)) | ||||||
|  | @ -191,7 +190,7 @@ public final class PermissionsUtil { | ||||||
| 	 * @return manifest permissions list | 	 * @return manifest permissions list | ||||||
| 	 * @throws PackageManager.NameNotFoundException the exception is thrown when a given package, application, or component name cannot be found. | 	 * @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(); | 		PackageManager packageManager = activity.getPackageManager(); | ||||||
| 		PackageInfo packageInfo = packageManager.getPackageInfo(activity.getPackageName(), PackageManager.GET_PERMISSIONS); | 		PackageInfo packageInfo = packageManager.getPackageInfo(activity.getPackageName(), PackageManager.GET_PERMISSIONS); | ||||||
| 		if (packageInfo.requestedPermissions == null) | 		if (packageInfo.requestedPermissions == null) | ||||||
|  | @ -206,7 +205,7 @@ public final class PermissionsUtil { | ||||||
| 	 * @return permission info object | 	 * @return permission info object | ||||||
| 	 * @throws PackageManager.NameNotFoundException the exception is thrown when a given package, application, or component name cannot be found. | 	 * @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(); | 		PackageManager packageManager = activity.getPackageManager(); | ||||||
| 		return packageManager.getPermissionInfo(permission, 0); | 		return packageManager.getPermissionInfo(permission, 0); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -1244,7 +1244,7 @@ JavaClassWrapper::JavaClassWrapper(jobject p_activity) { | ||||||
| 
 | 
 | ||||||
| 	JNIEnv *env = ThreadAndroid::get_env(); | 	JNIEnv *env = ThreadAndroid::get_env(); | ||||||
| 
 | 
 | ||||||
| 	jclass activityClass = env->FindClass("org/godotengine/godot/Godot"); | 	jclass activityClass = env->FindClass("android/app/Activity"); | ||||||
| 	jmethodID getClassLoader = env->GetMethodID(activityClass, "getClassLoader", "()Ljava/lang/ClassLoader;"); | 	jmethodID getClassLoader = env->GetMethodID(activityClass, "getClassLoader", "()Ljava/lang/ClassLoader;"); | ||||||
| 	classLoader = env->CallObjectMethod(p_activity, getClassLoader); | 	classLoader = env->CallObjectMethod(p_activity, getClassLoader); | ||||||
| 	classLoader = (jclass)env->NewGlobalRef(classLoader); | 	classLoader = (jclass)env->NewGlobalRef(classLoader); | ||||||
|  |  | ||||||
|  | @ -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 p_asset_manager, jboolean p_use_apk_expansion) { | 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) { | ||||||
| 
 | 
 | ||||||
| 	initialized = true; | 	initialized = true; | ||||||
| 
 | 
 | ||||||
|  | @ -128,7 +128,7 @@ JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_initialize(JNIEnv *en | ||||||
| 	env->GetJavaVM(&jvm); | 	env->GetJavaVM(&jvm); | ||||||
| 
 | 
 | ||||||
| 	// create our wrapper classes
 | 	// create our wrapper classes
 | ||||||
| 	godot_java = new GodotJavaWrapper(env, activity); // our activity is our godot instance is our activity..
 | 	godot_java = new GodotJavaWrapper(env, activity, godot_instance); | ||||||
| 	godot_io_java = new GodotIOJavaWrapper(env, godot_java->get_member_object("io", "Lorg/godotengine/godot/GodotIO;", env)); | 	godot_io_java = new GodotIOJavaWrapper(env, godot_java->get_member_object("io", "Lorg/godotengine/godot/GodotIO;", env)); | ||||||
| 
 | 
 | ||||||
| 	ThreadAndroid::make_default(jvm); | 	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); | 	godot_java->on_video_init(env); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz, jobject activity) { | JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz) { | ||||||
| 	// lets cleanup
 | 	// lets cleanup
 | ||||||
| 	if (godot_io_java) { | 	if (godot_io_java) { | ||||||
| 		delete godot_io_java; | 		delete godot_io_java; | ||||||
|  |  | ||||||
|  | @ -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.
 | // 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)
 | // 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" { | extern "C" { | ||||||
| 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_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, jobject activity); | JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_ondestroy(JNIEnv *env, jclass clazz); | ||||||
| JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_setup(JNIEnv *env, jclass clazz, jobjectArray p_cmdline); | 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_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); | JNIEXPORT void JNICALL Java_org_godotengine_godot_GodotLib_newcontext(JNIEnv *env, jclass clazz, jboolean p_32_bits); | ||||||
|  |  | ||||||
|  | @ -37,36 +37,47 @@ | ||||||
| 
 | 
 | ||||||
| // TODO we could probably create a base class for this...
 | // TODO we could probably create a base class for this...
 | ||||||
| 
 | 
 | ||||||
| GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance) { | GodotJavaWrapper::GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_godot_instance) { | ||||||
| 	godot_instance = p_env->NewGlobalRef(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...
 | 	// get info about our Godot class so we can get pointers and stuff...
 | ||||||
| 	cls = p_env->FindClass("org/godotengine/godot/Godot"); | 	godot_class = p_env->FindClass("org/godotengine/godot/Godot"); | ||||||
| 	if (cls) { | 	if (godot_class) { | ||||||
| 		cls = (jclass)p_env->NewGlobalRef(cls); | 		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); | ||||||
| 	} else { | 	} else { | ||||||
| 		// this is a pretty serious fail.. bail... pointers will stay 0
 | 		// this is a pretty serious fail.. bail... pointers will stay 0
 | ||||||
| 		return; | 		return; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	// get some method pointers...
 | 	// get some Godot method pointers...
 | ||||||
| 	_on_video_init = p_env->GetMethodID(cls, "onVideoInit", "()V"); | 	_on_video_init = p_env->GetMethodID(godot_class, "onVideoInit", "()V"); | ||||||
| 	_restart = p_env->GetMethodID(cls, "restart", "()V"); | 	_restart = p_env->GetMethodID(godot_class, "restart", "()V"); | ||||||
| 	_finish = p_env->GetMethodID(cls, "forceQuit", "()V"); | 	_finish = p_env->GetMethodID(godot_class, "forceQuit", "()V"); | ||||||
| 	_set_keep_screen_on = p_env->GetMethodID(cls, "setKeepScreenOn", "(Z)V"); | 	_set_keep_screen_on = p_env->GetMethodID(godot_class, "setKeepScreenOn", "(Z)V"); | ||||||
| 	_alert = p_env->GetMethodID(cls, "alert", "(Ljava/lang/String;Ljava/lang/String;)V"); | 	_alert = p_env->GetMethodID(godot_class, "alert", "(Ljava/lang/String;Ljava/lang/String;)V"); | ||||||
| 	_get_GLES_version_code = p_env->GetMethodID(cls, "getGLESVersionCode", "()I"); | 	_get_GLES_version_code = p_env->GetMethodID(godot_class, "getGLESVersionCode", "()I"); | ||||||
| 	_get_clipboard = p_env->GetMethodID(cls, "getClipboard", "()Ljava/lang/String;"); | 	_get_clipboard = p_env->GetMethodID(godot_class, "getClipboard", "()Ljava/lang/String;"); | ||||||
| 	_set_clipboard = p_env->GetMethodID(cls, "setClipboard", "(Ljava/lang/String;)V"); | 	_set_clipboard = p_env->GetMethodID(godot_class, "setClipboard", "(Ljava/lang/String;)V"); | ||||||
| 	_request_permission = p_env->GetMethodID(cls, "requestPermission", "(Ljava/lang/String;)Z"); | 	_request_permission = p_env->GetMethodID(godot_class, "requestPermission", "(Ljava/lang/String;)Z"); | ||||||
| 	_request_permissions = p_env->GetMethodID(cls, "requestPermissions", "()Z"); | 	_request_permissions = p_env->GetMethodID(godot_class, "requestPermissions", "()Z"); | ||||||
| 	_get_granted_permissions = p_env->GetMethodID(cls, "getGrantedPermissions", "()[Ljava/lang/String;"); | 	_get_granted_permissions = p_env->GetMethodID(godot_class, "getGrantedPermissions", "()[Ljava/lang/String;"); | ||||||
| 	_init_input_devices = p_env->GetMethodID(cls, "initInputDevices", "()V"); | 	_init_input_devices = p_env->GetMethodID(godot_class, "initInputDevices", "()V"); | ||||||
| 	_get_surface = p_env->GetMethodID(cls, "getSurface", "()Landroid/view/Surface;"); | 	_get_surface = p_env->GetMethodID(godot_class, "getSurface", "()Landroid/view/Surface;"); | ||||||
| 	_is_activity_resumed = p_env->GetMethodID(cls, "isActivityResumed", "()Z"); | 	_is_activity_resumed = p_env->GetMethodID(godot_class, "isActivityResumed", "()Z"); | ||||||
| 	_vibrate = p_env->GetMethodID(cls, "vibrate", "(I)V"); | 	_vibrate = p_env->GetMethodID(godot_class, "vibrate", "(I)V"); | ||||||
| 	_get_input_fallback_mapping = p_env->GetMethodID(cls, "getInputFallbackMapping", "()Ljava/lang/String;"); | 	_get_input_fallback_mapping = p_env->GetMethodID(godot_class, "getInputFallbackMapping", "()Ljava/lang/String;"); | ||||||
| 	_on_godot_main_loop_started = p_env->GetMethodID(cls, "onGodotMainLoopStarted", "()V"); | 	_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;"); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| GodotJavaWrapper::~GodotJavaWrapper() { | GodotJavaWrapper::~GodotJavaWrapper() { | ||||||
|  | @ -74,27 +85,25 @@ GodotJavaWrapper::~GodotJavaWrapper() { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| jobject GodotJavaWrapper::get_activity() { | jobject GodotJavaWrapper::get_activity() { | ||||||
| 	// our godot instance is our activity
 | 	return activity; | ||||||
| 	return godot_instance; |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| jobject GodotJavaWrapper::get_member_object(const char *p_name, const char *p_class, JNIEnv *p_env) { | jobject GodotJavaWrapper::get_member_object(const char *p_name, const char *p_class, JNIEnv *p_env) { | ||||||
| 	if (cls) { | 	if (godot_class) { | ||||||
| 		if (p_env == NULL) | 		if (p_env == NULL) | ||||||
| 			p_env = ThreadAndroid::get_env(); | 			p_env = ThreadAndroid::get_env(); | ||||||
| 
 | 
 | ||||||
| 		jfieldID fid = p_env->GetStaticFieldID(cls, p_name, p_class); | 		jfieldID fid = p_env->GetStaticFieldID(godot_class, p_name, p_class); | ||||||
| 		return p_env->GetStaticObjectField(cls, fid); | 		return p_env->GetStaticObjectField(godot_class, fid); | ||||||
| 	} else { | 	} else { | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| jobject GodotJavaWrapper::get_class_loader() { | jobject GodotJavaWrapper::get_class_loader() { | ||||||
| 	if (cls) { | 	if (_get_class_loader) { | ||||||
| 		JNIEnv *env = ThreadAndroid::get_env(); | 		JNIEnv *env = ThreadAndroid::get_env(); | ||||||
| 		jmethodID getClassLoader = env->GetMethodID(cls, "getClassLoader", "()Ljava/lang/ClassLoader;"); | 		return env->CallObjectMethod(godot_instance, _get_class_loader); | ||||||
| 		return env->CallObjectMethod(godot_instance, getClassLoader); |  | ||||||
| 	} else { | 	} else { | ||||||
| 		return NULL; | 		return NULL; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -43,7 +43,9 @@ | ||||||
| class GodotJavaWrapper { | class GodotJavaWrapper { | ||||||
| private: | private: | ||||||
| 	jobject godot_instance; | 	jobject godot_instance; | ||||||
| 	jclass cls; | 	jobject activity; | ||||||
|  | 	jclass godot_class; | ||||||
|  | 	jclass activity_class; | ||||||
| 
 | 
 | ||||||
| 	jmethodID _on_video_init = 0; | 	jmethodID _on_video_init = 0; | ||||||
| 	jmethodID _restart = 0; | 	jmethodID _restart = 0; | ||||||
|  | @ -62,9 +64,10 @@ private: | ||||||
| 	jmethodID _vibrate = 0; | 	jmethodID _vibrate = 0; | ||||||
| 	jmethodID _get_input_fallback_mapping = 0; | 	jmethodID _get_input_fallback_mapping = 0; | ||||||
| 	jmethodID _on_godot_main_loop_started = 0; | 	jmethodID _on_godot_main_loop_started = 0; | ||||||
|  | 	jmethodID _get_class_loader = 0; | ||||||
| 
 | 
 | ||||||
| public: | public: | ||||||
| 	GodotJavaWrapper(JNIEnv *p_env, jobject p_godot_instance); | 	GodotJavaWrapper(JNIEnv *p_env, jobject p_activity, jobject p_godot_instance); | ||||||
| 	~GodotJavaWrapper(); | 	~GodotJavaWrapper(); | ||||||
| 
 | 
 | ||||||
| 	jobject get_activity(); | 	jobject get_activity(); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Rémi Verschelde
						Rémi Verschelde