FAudioGMS/gamemaker/extensions/FAudioGMS/AndroidSource/Sdk/org.screwyoyo.faudiogms/src/main/java/org/libsdl/app/SDLActivity.java

617 lines
18 KiB
Java

package org.libsdl.app;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.UiModeManager;
import android.content.ClipboardManager;
import android.content.ClipData;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.drawable.Drawable;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.InputType;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.SparseArray;
import android.view.Display;
import android.view.Gravity;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.PointerIcon;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Hashtable;
import java.util.Locale;
/**
SDL Activity
*/
public class SDLActivity {
private static final String TAG = "yoyo";
public static boolean mIsResumedCalled, mHasFocus;
public static Locale mCurrentLocale;
// Handle the state of the native layer
public enum NativeState {
INIT, RESUMED, PAUSED
}
public static NativeState mNextNativeState;
public static NativeState mCurrentNativeState;
// Main components
public static SDLActivity mSingleton;
/**
* This method is called by SDL before loading the native shared libraries.
* It can be overridden to provide names of shared libraries to be loaded.
* The default implementation returns the defaults. It never returns null.
* An array returned by a new implementation must at least contain "SDL2".
* Also keep in mind that the order the libraries are loaded may matter.
* @return names of shared libraries to be loaded (e.g. "SDL2", "main").
*/
public String[] getLibraries() {
return new String[] {
"hidapi",
"SDL2",
"FAudioGMS"
};
}
// Load the .so
public void loadLibraries() {
for (String lib : getLibraries()) {
SDL.loadLibrary(lib);
}
}
public static void initialize() {
// The static nature of the singleton and Android quirkyness force us to initialize everything here
// Otherwise, when exiting the app and returning to it, these variables *keep* their pre exit values
mSingleton = null;
mIsResumedCalled = false;
mHasFocus = true;
mNextNativeState = NativeState.INIT;
mCurrentNativeState = NativeState.INIT;
}
// Setup
public void onCreate(Bundle savedInstanceState) {
Log.v(TAG, "Device: " + Build.DEVICE);
Log.v(TAG, "Model: " + Build.MODEL);
Log.v(TAG, "onCreate()");
try {
Thread.currentThread().setName("SDLActivity");
} catch (Exception e) {
Log.v(TAG, "modify thread properties failed " + e.toString());
}
// Load shared libraries
loadLibraries();
// Set up JNI
SDL.setupJNI();
// Initialize state
SDL.initialize();
// So we can call stuff from static callbacks
mSingleton = this;
}
public void pauseNativeThread() {
mNextNativeState = NativeState.PAUSED;
mIsResumedCalled = false;
SDLActivity.handleNativeState();
}
public void resumeNativeThread() {
mNextNativeState = NativeState.RESUMED;
mIsResumedCalled = true;
SDLActivity.handleNativeState();
}
// Events
public void onPause() {
Log.v(TAG, "onPause()");
pauseNativeThread();
}
public void onResume() {
Log.v(TAG, "onResume()");
resumeNativeThread();
}
public void onStop() {
Log.v(TAG, "onStop()");
pauseNativeThread();
}
public void onStart() {
Log.v(TAG, "onStart()");
resumeNativeThread();
}
public void onWindowFocusChanged(boolean hasFocus) {
Log.v(TAG, "onWindowFocusChanged(): " + hasFocus);
mHasFocus = hasFocus;
if (hasFocus) {
mNextNativeState = NativeState.RESUMED;
SDLActivity.handleNativeState();
nativeFocusChanged(true);
} else {
nativeFocusChanged(false);
mNextNativeState = NativeState.PAUSED;
SDLActivity.handleNativeState();
}
}
public void onLowMemory() {
Log.v(TAG, "onLowMemory()");
SDLActivity.nativeLowMemory();
}
public void onConfigurationChanged(Configuration newConfig) {
Log.v(TAG, "onConfigurationChanged()");
if (mCurrentLocale == null || !mCurrentLocale.equals(newConfig.locale)) {
mCurrentLocale = newConfig.locale;
SDLActivity.onNativeLocaleChanged();
}
}
public void onDestroy() {
Log.v(TAG, "onDestroy()");
SDLActivity.nativeSendQuit();
SDLActivity.nativeQuit();
}
// Called by JNI from SDL.
public static void manualBackButton() {
}
/* Transition to next state */
public static void handleNativeState() {
if (mNextNativeState == mCurrentNativeState) {
// Already in same state, discard.
return;
}
// Try a transition to init state
if (mNextNativeState == NativeState.INIT) {
mCurrentNativeState = mNextNativeState;
return;
}
// Try a transition to paused state
if (mNextNativeState == NativeState.PAUSED) {
nativePause();
mCurrentNativeState = mNextNativeState;
Log.i("yoyo", "SDL - PAUSE!");
return;
}
// Try a transition to resumed state
if (mNextNativeState == NativeState.RESUMED) {
nativeResume();
mCurrentNativeState = mNextNativeState;
Log.i("yoyo", "SDL - RESUME!");
return;
}
}
/**
* This method is called by SDL if SDL did not handle a message itself.
* This happens if a received message contains an unsupported command.
* Method can be overwritten to handle Messages in a different class.
* @param command the command of the message.
* @param param the parameter of the message. May be null.
* @return if the message was handled in overridden method.
*/
public boolean onUnhandledMessage(int command, Object param) {
return false;
}
/**
* A Handler class for Messages from native SDL applications.
* It uses current Activities as target (e.g. for the title).
* static to prevent implicit references to enclosing object.
*/
public static class SDLCommandHandler extends Handler {
@Override
public void handleMessage(Message msg) {
}
}
// Handler for the messages
Handler commandHandler = new SDLCommandHandler();
// Send a message from the SDLMain thread
boolean sendCommand(int command, Object data) {
Message msg = commandHandler.obtainMessage();
msg.arg1 = command;
msg.obj = data;
boolean result = commandHandler.sendMessage(msg);
return result;
}
// C functions we call
public static native int nativeSetupJNI();
public static native int nativeRunMain(String library, String function, Object arguments);
public static native void nativeLowMemory();
public static native void nativeSendQuit();
public static native void nativeQuit();
public static native void nativePause();
public static native void nativeResume();
public static native void nativeFocusChanged(boolean hasFocus);
public static native void onNativeDropFile(String filename);
public static native void nativeSetScreenResolution(int surfaceWidth, int surfaceHeight, int deviceWidth, int deviceHeight, float rate);
public static native void onNativeResize();
public static native void onNativeKeyDown(int keycode);
public static native void onNativeKeyUp(int keycode);
public static native boolean onNativeSoftReturnKey();
public static native void onNativeKeyboardFocusLost();
public static native void onNativeMouse(int button, int action, float x, float y, boolean relative);
public static native void onNativeTouch(int touchDevId, int pointerFingerId,
int action, float x,
float y, float p);
public static native void onNativeAccel(float x, float y, float z);
public static native void onNativeClipboardChanged();
public static native void onNativeSurfaceCreated();
public static native void onNativeSurfaceChanged();
public static native void onNativeSurfaceDestroyed();
public static native String nativeGetHint(String name);
public static native void nativeSetenv(String name, String value);
public static native void onNativeOrientationChanged(int orientation);
public static native void nativeAddTouch(int touchId, String name);
public static native void nativePermissionResult(int requestCode, boolean result);
public static native void onNativeLocaleChanged();
/**
* This method is called by SDL using JNI.
*/
public static boolean setActivityTitle(String title) {
return false;
}
/**
* This method is called by SDL using JNI.
*/
public static void setWindowStyle(boolean fullscreen) {
}
/**
* This method is called by SDL using JNI.
* This is a static method for JNI convenience, it calls a non-static method
* so that is can be overridden
*/
public static void setOrientation(int w, int h, boolean resizable, String hint){
}
/**
* This can be overridden
*/
public void setOrientationBis(int w, int h, boolean resizable, String hint){
}
/**
* This method is called by SDL using JNI.
*/
public static void minimizeWindow() {
}
/**
* This method is called by SDL using JNI.
*/
public static boolean shouldMinimizeOnFocusLoss() {
return false;
}
/**
* This method is called by SDL using JNI.
*/
public static boolean isScreenKeyboardShown(){
return false;
}
/**
* This method is called by SDL using JNI.
*/
public static boolean supportsRelativeMouse(){
return false;
}
/**
* This method is called by SDL using JNI.
*/
public static boolean setRelativeMouseEnabled(boolean enabled) {
return false;
}
/**
* This method is called by SDL using JNI.
*/
public static boolean sendMessage(int command, int param) {
return false;
}
/**
* This method is called by SDL using JNI.
*/
public static Context getContext() {
return SDL.getContext();
}
/**
* This method is called by SDL using JNI.
*/
public static boolean isAndroidTV() {
return false;
}
public static double getDiagonal() {
return 0.0;
}
/**
* This method is called by SDL using JNI.
*/
public static boolean isTablet() {
return false;
}
/**
* This method is called by SDL using JNI.
*/
public static boolean isChromebook() {
return false;
}
/**
* This method is called by SDL using JNI.
*/
public static boolean isDeXMode() {
return false;
}
/**
* This method is called by SDL using JNI.
*/
public static DisplayMetrics getDisplayDPI() {
return getContext().getResources().getDisplayMetrics();
}
/**
* This method is called by SDL using JNI.
*/
public static boolean getManifestEnvironmentVariables() {
Log.i("yoyo", "sdl envvars req!");
nativeSetenv("SDL_ANDROID_BLOCK_ON_PAUSE", "1");
nativeSetenv("SDL_ANDROID_BLOCK_ON_PAUSE_PAUSEAUDIO", "1");
Log.i("yoyo", "sdl envvars ok!");
return true;
}
/**
* This method is called by SDL using JNI.
*/
public static boolean showTextInput(int x, int y, int w, int h) {
return false;
}
/**
* This method is called by SDL using JNI.
*/
public static Surface getNativeSurface() {
return null;
}
// Input
/**
* This method is called by SDL using JNI.
*/
public static void initTouch() {
}
// Messagebox
/** Result of current messagebox. Also used for blocking the calling thread. */
public final int[] messageboxSelection = new int[1];
/**
* This method is called by SDL using JNI.
* Shows the messagebox from UI thread and block calling thread.
* buttonFlags, buttonIds and buttonTexts must have same length.
* @param buttonFlags array containing flags for every button.
* @param buttonIds array containing id for every button.
* @param buttonTexts array containing text for every button.
* @param colors null for default or array of length 5 containing colors.
* @return button id or -1.
*/
public int messageboxShowMessageBox(
final int flags,
final String title,
final String message,
final int[] buttonFlags,
final int[] buttonIds,
final String[] buttonTexts,
final int[] colors) {
return -1;
}
public void messageboxCreateAndShow(Bundle args) {
}
private final Runnable rehideSystemUi = new Runnable() {
@Override
public void run() {
}
};
public void onSystemUiVisibilityChange(int visibility) {
}
/**
* This method is called by SDL using JNI.
*/
public static boolean clipboardHasText() {
return false;
}
/**
* This method is called by SDL using JNI.
*/
public static String clipboardGetText() {
return "";
}
/**
* This method is called by SDL using JNI.
*/
public static void clipboardSetText(String string) {
}
/**
* This method is called by SDL using JNI.
*/
public static int createCustomCursor(int[] colors, int width, int height, int hotSpotX, int hotSpotY) {
return 0;
}
/**
* This method is called by SDL using JNI.
*/
public static boolean setCustomCursor(int cursorID) {
return false;
}
/**
* This method is called by SDL using JNI.
*/
public static boolean setSystemCursor(int cursorID) {
return false;
}
/**
* This method is called by SDL using JNI.
*/
public static void requestPermission(String permission, int requestCode) {
if (Build.VERSION.SDK_INT < 23) {
nativePermissionResult(requestCode, true);
return;
}
Activity activity = (Activity)getContext();
if (activity.checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
activity.requestPermissions(new String[]{permission}, requestCode);
} else {
nativePermissionResult(requestCode, true);
}
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
boolean result = (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED);
nativePermissionResult(requestCode, result);
}
/**
* This method is called by SDL using JNI.
*/
public static int openURL(String url) {
return -1;
}
/**
* This method is called by SDL using JNI.
*/
public static int showToast(String message, int duration, int gravity, int xOffset, int yOffset) {
return -1;
}
}
/**
Simple runnable to start the SDL application
*/
class SDLMain implements Runnable {
@Override
public void run() {
try {
android.os.Process.setThreadPriority(android.os.Process.THREAD_PRIORITY_DISPLAY);
} catch (Exception e) {
Log.v("SDL", "modify thread properties failed " + e.toString());
}
}
}
class SDLInputConnection extends BaseInputConnection {
public SDLInputConnection(View targetView, boolean fullEditor) {
super(targetView, fullEditor);
}
public boolean sendKeyEvent(KeyEvent event) {
return false;
}
public boolean commitText(CharSequence text, int newCursorPosition) {
return false;
}
public boolean setComposingText(CharSequence text, int newCursorPosition) {
return false;
}
public static native void nativeCommitText(String text, int newCursorPosition);
public native void nativeGenerateScancodeForUnichar(char c);
public native void nativeSetComposingText(String text, int newCursorPosition);
public boolean deleteSurroundingText(int beforeLength, int afterLength) {
return false;
}
}