/* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @addtogroup GameActivity Game Activity * The interface to use GameActivity. * @{ */ /** * @file GameActivity.h */ #ifndef ANDROID_GAME_SDK_GAME_ACTIVITY_H #define ANDROID_GAME_SDK_GAME_ACTIVITY_H #include #include #include #include #include #include #include #include #include "common/gamesdk_common.h" #include "game-activity/GameActivityEvents.h" #include "game-text-input/gametextinput.h" #ifdef __cplusplus extern "C" { #endif #define GAMEACTIVITY_MAJOR_VERSION 2 #define GAMEACTIVITY_MINOR_VERSION 0 #define GAMEACTIVITY_BUGFIX_VERSION 2 #define GAMEACTIVITY_PACKED_VERSION \ ANDROID_GAMESDK_PACKED_VERSION(GAMEACTIVITY_MAJOR_VERSION, \ GAMEACTIVITY_MINOR_VERSION, \ GAMEACTIVITY_BUGFIX_VERSION) /** * {@link GameActivityCallbacks} */ struct GameActivityCallbacks; /** * This structure defines the native side of an android.app.GameActivity. * It is created by the framework, and handed to the application's native * code as it is being launched. */ typedef struct GameActivity { /** * Pointer to the callback function table of the native application. * You can set the functions here to your own callbacks. The callbacks * pointer itself here should not be changed; it is allocated and managed * for you by the framework. */ struct GameActivityCallbacks* callbacks; /** * The global handle on the process's Java VM. */ JavaVM* vm; /** * JNI context for the main thread of the app. Note that this field * can ONLY be used from the main thread of the process; that is, the * thread that calls into the GameActivityCallbacks. */ JNIEnv* env; /** * The GameActivity object handle. */ jobject javaGameActivity; /** * Path to this application's internal data directory. */ const char* internalDataPath; /** * Path to this application's external (removable/mountable) data directory. */ const char* externalDataPath; /** * The platform's SDK version code. */ int32_t sdkVersion; /** * This is the native instance of the application. It is not used by * the framework, but can be set by the application to its own instance * state. */ void* instance; /** * Pointer to the Asset Manager instance for the application. The * application uses this to access binary assets bundled inside its own .apk * file. */ AAssetManager* assetManager; /** * Available starting with Honeycomb: path to the directory containing * the application's OBB files (if any). If the app doesn't have any * OBB files, this directory may not exist. */ const char* obbPath; } GameActivity; /** * A function the user should call from their callback with the data, its length * and the library- supplied context. */ typedef void (*SaveInstanceStateRecallback)(const char* bytes, int len, void* context); /** * These are the callbacks the framework makes into a native application. * All of these callbacks happen on the main thread of the application. * By default, all callbacks are NULL; set to a pointer to your own function * to have it called. */ typedef struct GameActivityCallbacks { /** * GameActivity has started. See Java documentation for Activity.onStart() * for more information. */ void (*onStart)(GameActivity* activity); /** * GameActivity has resumed. See Java documentation for Activity.onResume() * for more information. */ void (*onResume)(GameActivity* activity); /** * The framework is asking GameActivity to save its current instance state. * See the Java documentation for Activity.onSaveInstanceState() for more * information. The user should call the recallback with their data, its * length and the provided context; they retain ownership of the data. Note * that the saved state will be persisted, so it can not contain any active * entities (pointers to memory, file descriptors, etc). */ void (*onSaveInstanceState)(GameActivity* activity, SaveInstanceStateRecallback recallback, void* context); /** * GameActivity has paused. See Java documentation for Activity.onPause() * for more information. */ void (*onPause)(GameActivity* activity); /** * GameActivity has stopped. See Java documentation for Activity.onStop() * for more information. */ void (*onStop)(GameActivity* activity); /** * GameActivity is being destroyed. See Java documentation for * Activity.onDestroy() for more information. */ void (*onDestroy)(GameActivity* activity); /** * Focus has changed in this GameActivity's window. This is often used, * for example, to pause a game when it loses input focus. */ void (*onWindowFocusChanged)(GameActivity* activity, bool hasFocus); /** * The drawing window for this native activity has been created. You * can use the given native window object to start drawing. */ void (*onNativeWindowCreated)(GameActivity* activity, ANativeWindow* window); /** * The drawing window for this native activity has been resized. You should * retrieve the new size from the window and ensure that your rendering in * it now matches. */ void (*onNativeWindowResized)(GameActivity* activity, ANativeWindow* window, int32_t newWidth, int32_t newHeight); /** * The drawing window for this native activity needs to be redrawn. To * avoid transient artifacts during screen changes (such resizing after * rotation), applications should not return from this function until they * have finished drawing their window in its current state. */ void (*onNativeWindowRedrawNeeded)(GameActivity* activity, ANativeWindow* window); /** * The drawing window for this native activity is going to be destroyed. * You MUST ensure that you do not touch the window object after returning * from this function: in the common case of drawing to the window from * another thread, that means the implementation of this callback must * properly synchronize with the other thread to stop its drawing before * returning from here. */ void (*onNativeWindowDestroyed)(GameActivity* activity, ANativeWindow* window); /** * The current device AConfiguration has changed. The new configuration can * be retrieved from assetManager. */ void (*onConfigurationChanged)(GameActivity* activity); /** * The system is running low on memory. Use this callback to release * resources you do not need, to help the system avoid killing more * important processes. */ void (*onTrimMemory)(GameActivity* activity, int level); /** * Callback called for every MotionEvent done on the GameActivity * SurfaceView. Ownership of `event` is maintained by the library and it is * only valid during the callback. */ bool (*onTouchEvent)(GameActivity* activity, const GameActivityMotionEvent* event); /** * Callback called for every key down event on the GameActivity SurfaceView. * Ownership of `event` is maintained by the library and it is only valid * during the callback. */ bool (*onKeyDown)(GameActivity* activity, const GameActivityKeyEvent* event); /** * Callback called for every key up event on the GameActivity SurfaceView. * Ownership of `event` is maintained by the library and it is only valid * during the callback. */ bool (*onKeyUp)(GameActivity* activity, const GameActivityKeyEvent* event); /** * Callback called for every soft-keyboard text input event. * Ownership of `state` is maintained by the library and it is only valid * during the callback. */ void (*onTextInputEvent)(GameActivity* activity, const GameTextInputState* state); /** * Callback called when WindowInsets of the main app window have changed. * Call GameActivity_getWindowInsets to retrieve the insets themselves. */ void (*onWindowInsetsChanged)(GameActivity* activity); /** * Callback called when the rectangle in the window where the content * should be placed has changed. */ void (*onContentRectChanged)(GameActivity *activity, const ARect *rect); } GameActivityCallbacks; /** * This is the function that must be in the native code to instantiate the * application's native activity. It is called with the activity instance (see * above); if the code is being instantiated from a previously saved instance, * the savedState will be non-NULL and point to the saved data. You must make * any copy of this data you need -- it will be released after you return from * this function. */ typedef void GameActivity_createFunc(GameActivity* activity, void* savedState, size_t savedStateSize); /** * The name of the function that NativeInstance looks for when launching its * native code. This is the default function that is used, you can specify * "android.app.func_name" string meta-data in your manifest to use a different * function. */ extern GameActivity_createFunc GameActivity_onCreate_C; /** * Finish the given activity. Its finish() method will be called, causing it * to be stopped and destroyed. Note that this method can be called from * *any* thread; it will send a message to the main thread of the process * where the Java finish call will take place. */ void GameActivity_finish(GameActivity* activity); /** * Flags for GameActivity_setWindowFlags, * as per the Java API at android.view.WindowManager.LayoutParams. */ enum GameActivitySetWindowFlags { /** * As long as this window is visible to the user, allow the lock * screen to activate while the screen is on. This can be used * independently, or in combination with {@link * GAMEACTIVITY_FLAG_KEEP_SCREEN_ON} and/or {@link * GAMEACTIVITY_FLAG_SHOW_WHEN_LOCKED} */ GAMEACTIVITY_FLAG_ALLOW_LOCK_WHILE_SCREEN_ON = 0x00000001, /** Everything behind this window will be dimmed. */ GAMEACTIVITY_FLAG_DIM_BEHIND = 0x00000002, /** * Blur everything behind this window. * @deprecated Blurring is no longer supported. */ GAMEACTIVITY_FLAG_BLUR_BEHIND = 0x00000004, /** * This window won't ever get key input focus, so the * user can not send key or other button events to it. Those will * instead go to whatever focusable window is behind it. This flag * will also enable {@link GAMEACTIVITY_FLAG_NOT_TOUCH_MODAL} whether or not * that is explicitly set. * * Setting this flag also implies that the window will not need to * interact with * a soft input method, so it will be Z-ordered and positioned * independently of any active input method (typically this means it * gets Z-ordered on top of the input method, so it can use the full * screen for its content and cover the input method if needed. You * can use {@link GAMEACTIVITY_FLAG_ALT_FOCUSABLE_IM} to modify this * behavior. */ GAMEACTIVITY_FLAG_NOT_FOCUSABLE = 0x00000008, /** This window can never receive touch events. */ GAMEACTIVITY_FLAG_NOT_TOUCHABLE = 0x00000010, /** * Even when this window is focusable (its * {@link GAMEACTIVITY_FLAG_NOT_FOCUSABLE} is not set), allow any pointer * events outside of the window to be sent to the windows behind it. * Otherwise it will consume all pointer events itself, regardless of * whether they are inside of the window. */ GAMEACTIVITY_FLAG_NOT_TOUCH_MODAL = 0x00000020, /** * When set, if the device is asleep when the touch * screen is pressed, you will receive this first touch event. Usually * the first touch event is consumed by the system since the user can * not see what they are pressing on. * * @deprecated This flag has no effect. */ GAMEACTIVITY_FLAG_TOUCHABLE_WHEN_WAKING = 0x00000040, /** * As long as this window is visible to the user, keep * the device's screen turned on and bright. */ GAMEACTIVITY_FLAG_KEEP_SCREEN_ON = 0x00000080, /** * Place the window within the entire screen, ignoring * decorations around the border (such as the status bar). The * window must correctly position its contents to take the screen * decoration into account. */ GAMEACTIVITY_FLAG_LAYOUT_IN_SCREEN = 0x00000100, /** Allows the window to extend outside of the screen. */ GAMEACTIVITY_FLAG_LAYOUT_NO_LIMITS = 0x00000200, /** * Hide all screen decorations (such as the status * bar) while this window is displayed. This allows the window to * use the entire display space for itself -- the status bar will * be hidden when an app window with this flag set is on the top * layer. A fullscreen window will ignore a value of {@link * GAMEACTIVITY_SOFT_INPUT_ADJUST_RESIZE}; the window will stay * fullscreen and will not resize. */ GAMEACTIVITY_FLAG_FULLSCREEN = 0x00000400, /** * Override {@link GAMEACTIVITY_FLAG_FULLSCREEN} and force the * screen decorations (such as the status bar) to be shown. */ GAMEACTIVITY_FLAG_FORCE_NOT_FULLSCREEN = 0x00000800, /** * Turn on dithering when compositing this window to * the screen. * @deprecated This flag is no longer used. */ GAMEACTIVITY_FLAG_DITHER = 0x00001000, /** * Treat the content of the window as secure, preventing * it from appearing in screenshots or from being viewed on non-secure * displays. */ GAMEACTIVITY_FLAG_SECURE = 0x00002000, /** * A special mode where the layout parameters are used * to perform scaling of the surface when it is composited to the * screen. */ GAMEACTIVITY_FLAG_SCALED = 0x00004000, /** * Intended for windows that will often be used when the user is * holding the screen against their face, it will aggressively * filter the event stream to prevent unintended presses in this * situation that may not be desired for a particular window, when * such an event stream is detected, the application will receive * a {@link AMOTION_EVENT_ACTION_CANCEL} to indicate this so * applications can handle this accordingly by taking no action on * the event until the finger is released. */ GAMEACTIVITY_FLAG_IGNORE_CHEEK_PRESSES = 0x00008000, /** * A special option only for use in combination with * {@link GAMEACTIVITY_FLAG_LAYOUT_IN_SCREEN}. When requesting layout in * the screen your window may appear on top of or behind screen decorations * such as the status bar. By also including this flag, the window * manager will report the inset rectangle needed to ensure your * content is not covered by screen decorations. */ GAMEACTIVITY_FLAG_LAYOUT_INSET_DECOR = 0x00010000, /** * Invert the state of {@link GAMEACTIVITY_FLAG_NOT_FOCUSABLE} with * respect to how this window interacts with the current method. * That is, if FLAG_NOT_FOCUSABLE is set and this flag is set, * then the window will behave as if it needs to interact with the * input method and thus be placed behind/away from it; if {@link * GAMEACTIVITY_FLAG_NOT_FOCUSABLE} is not set and this flag is set, * then the window will behave as if it doesn't need to interact * with the input method and can be placed to use more space and * cover the input method. */ GAMEACTIVITY_FLAG_ALT_FOCUSABLE_IM = 0x00020000, /** * If you have set {@link GAMEACTIVITY_FLAG_NOT_TOUCH_MODAL}, you * can set this flag to receive a single special MotionEvent with * the action * {@link AMOTION_EVENT_ACTION_OUTSIDE} for * touches that occur outside of your window. Note that you will not * receive the full down/move/up gesture, only the location of the * first down as an {@link AMOTION_EVENT_ACTION_OUTSIDE}. */ GAMEACTIVITY_FLAG_WATCH_OUTSIDE_TOUCH = 0x00040000, /** * Special flag to let windows be shown when the screen * is locked. This will let application windows take precedence over * key guard or any other lock screens. Can be used with * {@link GAMEACTIVITY_FLAG_KEEP_SCREEN_ON} to turn screen on and display * windows directly before showing the key guard window. Can be used with * {@link GAMEACTIVITY_FLAG_DISMISS_KEYGUARD} to automatically fully * dismisss non-secure keyguards. This flag only applies to the top-most * full-screen window. */ GAMEACTIVITY_FLAG_SHOW_WHEN_LOCKED = 0x00080000, /** * Ask that the system wallpaper be shown behind * your window. The window surface must be translucent to be able * to actually see the wallpaper behind it; this flag just ensures * that the wallpaper surface will be there if this window actually * has translucent regions. */ GAMEACTIVITY_FLAG_SHOW_WALLPAPER = 0x00100000, /** * When set as a window is being added or made * visible, once the window has been shown then the system will * poke the power manager's user activity (as if the user had woken * up the device) to turn the screen on. */ GAMEACTIVITY_FLAG_TURN_SCREEN_ON = 0x00200000, /** * When set the window will cause the keyguard to * be dismissed, only if it is not a secure lock keyguard. Because such * a keyguard is not needed for security, it will never re-appear if * the user navigates to another window (in contrast to * {@link GAMEACTIVITY_FLAG_SHOW_WHEN_LOCKED}, which will only temporarily * hide both secure and non-secure keyguards but ensure they reappear * when the user moves to another UI that doesn't hide them). * If the keyguard is currently active and is secure (requires an * unlock pattern) than the user will still need to confirm it before * seeing this window, unless {@link GAMEACTIVITY_FLAG_SHOW_WHEN_LOCKED} has * also been set. */ GAMEACTIVITY_FLAG_DISMISS_KEYGUARD = 0x00400000, }; /** * Change the window flags of the given activity. Calls getWindow().setFlags() * of the given activity. * Note that some flags must be set before the window decoration is created, * see * https://developer.android.com/reference/android/view/Window#setFlags(int,%20int). * Note also that this method can be called from * *any* thread; it will send a message to the main thread of the process * where the Java finish call will take place. */ void GameActivity_setWindowFlags(GameActivity* activity, uint32_t addFlags, uint32_t removeFlags); /** * Flags for GameActivity_showSoftInput; see the Java InputMethodManager * API for documentation. */ enum GameActivityShowSoftInputFlags { /** * Implicit request to show the input window, not as the result * of a direct request by the user. */ GAMEACTIVITY_SHOW_SOFT_INPUT_IMPLICIT = 0x0001, /** * The user has forced the input method open (such as by * long-pressing menu) so it should not be closed until they * explicitly do so. */ GAMEACTIVITY_SHOW_SOFT_INPUT_FORCED = 0x0002, }; /** * Show the IME while in the given activity. Calls * InputMethodManager.showSoftInput() for the given activity. Note that this * method can be called from *any* thread; it will send a message to the main * thread of the process where the Java call will take place. */ void GameActivity_showSoftInput(GameActivity* activity, uint32_t flags); /** * Set the text entry state (see documentation of the GameTextInputState struct * in the Game Text Input library reference). * * Ownership of the state is maintained by the caller. */ void GameActivity_setTextInputState(GameActivity* activity, const GameTextInputState* state); /** * Get the last-received text entry state (see documentation of the * GameTextInputState struct in the Game Text Input library reference). * */ void GameActivity_getTextInputState(GameActivity* activity, GameTextInputGetStateCallback callback, void* context); /** * Get a pointer to the GameTextInput library instance. */ GameTextInput* GameActivity_getTextInput(const GameActivity* activity); /** * Flags for GameActivity_hideSoftInput; see the Java InputMethodManager * API for documentation. */ enum GameActivityHideSoftInputFlags { /** * The soft input window should only be hidden if it was not * explicitly shown by the user. */ GAMEACTIVITY_HIDE_SOFT_INPUT_IMPLICIT_ONLY = 0x0001, /** * The soft input window should normally be hidden, unless it was * originally shown with {@link GAMEACTIVITY_SHOW_SOFT_INPUT_FORCED}. */ GAMEACTIVITY_HIDE_SOFT_INPUT_NOT_ALWAYS = 0x0002, }; /** * Hide the IME while in the given activity. Calls * InputMethodManager.hideSoftInput() for the given activity. Note that this * method can be called from *any* thread; it will send a message to the main * thread of the process where the Java finish call will take place. */ void GameActivity_hideSoftInput(GameActivity* activity, uint32_t flags); /** * Get the current window insets of the particular component. See * https://developer.android.com/reference/androidx/core/view/WindowInsetsCompat.Type * for more details. * You can use these insets to influence what you show on the screen. */ void GameActivity_getWindowInsets(GameActivity* activity, GameCommonInsetsType type, ARect* insets); /** * Set options on how the IME behaves when it is requested for text input. * See * https://developer.android.com/reference/android/view/inputmethod/EditorInfo * for the meaning of inputType, actionId and imeOptions. * * Note that this function will attach the current thread to the JVM if it is * not already attached, so the caller must detach the thread from the JVM * before the thread is destroyed using DetachCurrentThread. */ void GameActivity_setImeEditorInfo(GameActivity* activity, int inputType, int actionId, int imeOptions); /** * These are getters for Configuration class members. They may be called from * any thread. */ int GameActivity_getOrientation(GameActivity* activity); int GameActivity_getColorMode(GameActivity* activity); int GameActivity_getDensityDpi(GameActivity* activity); float GameActivity_getFontScale(GameActivity* activity); int GameActivity_getFontWeightAdjustment(GameActivity* activity); int GameActivity_getHardKeyboardHidden(GameActivity* activity); int GameActivity_getKeyboard(GameActivity* activity); int GameActivity_getKeyboardHidden(GameActivity* activity); int GameActivity_getMcc(GameActivity* activity); int GameActivity_getMnc(GameActivity* activity); int GameActivity_getNavigation(GameActivity* activity); int GameActivity_getNavigationHidden(GameActivity* activity); int GameActivity_getOrientation(GameActivity* activity); int GameActivity_getScreenHeightDp(GameActivity* activity); int GameActivity_getScreenLayout(GameActivity* activity); int GameActivity_getScreenWidthDp(GameActivity* activity); int GameActivity_getSmallestScreenWidthDp(GameActivity* activity); int GameActivity_getTouchscreen(GameActivity* activity); int GameActivity_getUIMode(GameActivity* activity); #ifdef __cplusplus } #endif /** @} */ #endif // ANDROID_GAME_SDK_GAME_ACTIVITY_H