Merge "GameController compat. fix for GameActivity 1.2"
diff --git a/OWNERS b/OWNERS
index 65e6ffb..21d473e 100644
--- a/OWNERS
+++ b/OWNERS
@@ -4,4 +4,5 @@
jeremyns@google.com
bkaya@google.com
tomnom@google.com
-eriste@google.com
\ No newline at end of file
+artyompp@google.com
+gvamsi@google.com
\ No newline at end of file
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index 49e4f95..760ffcf 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,8 +1,6 @@
[Hook Scripts]
-swappy_abi_hook = ${REPO_ROOT}/gamesdk/hooks/check_swappy_abi_version.sh ${PREUPLOAD_COMMIT} ${PREUPLOAD_FILES}
-tuningfork_abi_hook = ${REPO_ROOT}/gamesdk/hooks/check_tuningfork_abi_version.sh ${PREUPLOAD_COMMIT} ${PREUPLOAD_FILES}
-bugfix_hook = ${REPO_ROOT}/gamesdk/hooks/check_bugfix_version.sh ${PREUPLOAD_COMMIT} ${PREUPLOAD_FILES}
+versions_hook = ${REPO_ROOT}/gamesdk/hooks/check_library_versions.sh ${PREUPLOAD_COMMIT} ${PREUPLOAD_FILES}
[Builtin Hooks]
clang_format = true
diff --git a/VERSIONS b/VERSIONS
index c5930c7..2a2f1f4 100644
--- a/VERSIONS
+++ b/VERSIONS
@@ -6,10 +6,10 @@
# Nickname JetPackName ProjectName Version JetPackSubscript
#
AGDK NA NA 2022.1.1 alpha01
-swappy games-frame-pacing games-frame-pacing 1.10.2 alpha01
-tuningfork games-performance-tuner games-performance-tuner 1.6.1 alpha01
+swappy games-frame-pacing games-frame-pacing 2.0.0 alpha01
+tuningfork games-performance-tuner games-performance-tuner 2.0.0 alpha01
oboe oboe None 1.0.1 alpha01
-game_activity games-activity game-activity 1.2.2
-game_text_input games-text-input game-text-input 1.1.2 alpha01
-paddleboat games-controller games-controller 1.1.1 alpha01
-memory_advice games-memory-advice games-memory-advice 1.0.0 beta03
+game_activity games-activity game-activity 2.0.0 alpha01
+game_text_input games-text-input game-text-input 2.0.0 alpha01
+paddleboat games-controller games-controller 2.0.0 alpha01
+memory_advice games-memory-advice games-memory-advice 2.0.0 alpha01
diff --git a/build.sh b/build.sh
index efd28fa..ccda7d6 100755
--- a/build.sh
+++ b/build.sh
@@ -110,7 +110,7 @@
mkdir -p ./third-party
pushd third-party
if [ ! -d "imgui" ] ; then
- git clone https://github.com/ocornut/imgui
+ git clone https://github.com/ocornut/imgui -b v1.89
fi
popd
popd
diff --git a/game-activity/CMakeLists.txt b/game-activity/CMakeLists.txt
index e947466..9fda9b4 100644
--- a/game-activity/CMakeLists.txt
+++ b/game-activity/CMakeLists.txt
@@ -18,11 +18,13 @@
set(CMAKE_CXX_STANDARD 17)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/prefab-src/modules/game-activity/include/)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include/)
set(GAMEACTIVITY_SRC_DIR "${CMAKE_CURRENT_SOURCE_DIR}/prefab-src/modules/game-activity/include/")
set(GAMEACTIVITY_SRCS
${GAMEACTIVITY_SRC_DIR}/game-activity/GameActivity.cpp
+ ${GAMEACTIVITY_SRC_DIR}/game-activity/GameActivityEvents.cpp
${GAMEACTIVITY_SRC_DIR}/game-activity/native_app_glue/android_native_app_glue.c
${GAMEACTIVITY_SRC_DIR}/game-text-input/gametextinput.cpp)
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Werror -Os")
diff --git a/game-activity/prefab-src/modules/game-activity/include/common b/game-activity/prefab-src/modules/game-activity/include/common
new file mode 120000
index 0000000..9388f34
--- /dev/null
+++ b/game-activity/prefab-src/modules/game-activity/include/common
@@ -0,0 +1 @@
+../../../../../include/common/
\ No newline at end of file
diff --git a/game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivity.cpp b/game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivity.cpp
index dee363c..3c0e762 100644
--- a/game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivity.cpp
+++ b/game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivity.cpp
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-#define LOG_TAG "GameActivity"
#include "GameActivity.h"
@@ -39,30 +38,10 @@
#include <mutex>
#include <string>
-// TODO(b/187147166): these functions were extracted from the Game SDK
-// (gamesdk/src/common/system_utils.h). system_utils.h/cpp should be used
-// instead.
+#include "GameActivityLog.h"
+
namespace {
-std::string getSystemPropViaGet(const char *key,
- const char *default_value = "") {
- char buffer[PROP_VALUE_MAX + 1] = ""; // +1 for terminator
- int bufferLen = __system_property_get(key, buffer);
- if (bufferLen > 0)
- return buffer;
- else
- return "";
-}
-
-std::string GetSystemProp(const char *key, const char *default_value = "") {
- return getSystemPropViaGet(key, default_value);
-}
-
-int GetSystemPropAsInt(const char *key, int default_value = 0) {
- std::string prop = GetSystemProp(key);
- return prop == "" ? default_value : strtoll(prop.c_str(), nullptr, 10);
-}
-
struct OwnedGameTextInputState {
OwnedGameTextInputState &operator=(const GameTextInputState &rhs) {
inner = rhs;
@@ -76,93 +55,6 @@
} // anonymous namespace
-#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__);
-#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__);
-#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__);
-#ifdef NDEBUG
-#define ALOGV(...)
-#else
-#define ALOGV(...) \
- __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__);
-#endif
-
-/* Returns 2nd arg. Used to substitute default value if caller's vararg list
- * is empty.
- */
-#define __android_second(first, second, ...) second
-
-/* If passed multiple args, returns ',' followed by all but 1st arg, otherwise
- * returns nothing.
- */
-#define __android_rest(first, ...) , ##__VA_ARGS__
-
-#define android_printAssert(cond, tag, fmt...) \
- __android_log_assert(cond, tag, \
- __android_second(0, ##fmt, NULL) __android_rest(fmt))
-
-#define CONDITION(cond) (__builtin_expect((cond) != 0, 0))
-
-#ifndef LOG_ALWAYS_FATAL_IF
-#define LOG_ALWAYS_FATAL_IF(cond, ...) \
- ((CONDITION(cond)) \
- ? ((void)android_printAssert(#cond, LOG_TAG, ##__VA_ARGS__)) \
- : (void)0)
-#endif
-
-#ifndef LOG_ALWAYS_FATAL
-#define LOG_ALWAYS_FATAL(...) \
- (((void)android_printAssert(NULL, LOG_TAG, ##__VA_ARGS__)))
-#endif
-
-/*
- * Simplified macro to send a warning system log message using current LOG_TAG.
- */
-#ifndef SLOGW
-#define SLOGW(...) \
- ((void)__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
-#endif
-
-#ifndef SLOGW_IF
-#define SLOGW_IF(cond, ...) \
- ((__predict_false(cond)) \
- ? ((void)__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) \
- : (void)0)
-#endif
-
-/*
- * Versions of LOG_ALWAYS_FATAL_IF and LOG_ALWAYS_FATAL that
- * are stripped out of release builds.
- */
-#if LOG_NDEBUG
-
-#ifndef LOG_FATAL_IF
-#define LOG_FATAL_IF(cond, ...) ((void)0)
-#endif
-#ifndef LOG_FATAL
-#define LOG_FATAL(...) ((void)0)
-#endif
-
-#else
-
-#ifndef LOG_FATAL_IF
-#define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ##__VA_ARGS__)
-#endif
-#ifndef LOG_FATAL
-#define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__)
-#endif
-
-#endif
-
-/*
- * Assertion that generates a log message when the assertion fails.
- * Stripped out of release builds. Uses the current LOG_TAG.
- */
-#ifndef ALOG_ASSERT
-#define ALOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ##__VA_ARGS__)
-#endif
-
-#define LOG_TRACE(...)
-
#ifndef NELEM
#define NELEM(x) ((int)(sizeof(x) / sizeof((x)[0])))
#endif
@@ -189,6 +81,30 @@
} gInsetsClassInfo;
/*
+ * JNI fields of the Configuration Java class.
+ */
+static struct ConfigurationClassInfo {
+ jfieldID colorMode;
+ jfieldID densityDpi;
+ jfieldID fontScale;
+ jfieldID fontWeightAdjustment;
+ jfieldID hardKeyboardHidden;
+ jfieldID keyboard;
+ jfieldID keyboardHidden;
+ jfieldID mcc;
+ jfieldID mnc;
+ jfieldID navigation;
+ jfieldID navigationHidden;
+ jfieldID orientation;
+ jfieldID screenHeightDp;
+ jfieldID screenLayout;
+ jfieldID screenWidthDp;
+ jfieldID smallestScreenWidthDp;
+ jfieldID touchscreen;
+ jfieldID uiMode;
+} gConfigurationClassInfo;
+
+/*
* JNI methods of the WindowInsetsCompat.Type Java class.
*/
static struct {
@@ -222,6 +138,31 @@
};
/*
+ * Last known Configuration values. They may be accessed from the different
+ * thread, this is why they are made atomic.
+ */
+static struct Configuration {
+ std::atomic_int colorMode;
+ std::atomic_int densityDpi;
+ std::atomic<float> fontScale;
+ std::atomic_int fontWeightAdjustment;
+ std::atomic_int hardKeyboardHidden;
+ std::atomic_int keyboard;
+ std::atomic_int keyboardHidden;
+ std::atomic_int mcc;
+ std::atomic_int mnc;
+ std::atomic_int navigation;
+ std::atomic_int navigationHidden;
+ std::atomic_int orientation;
+ std::atomic_int screenHeightDp;
+ std::atomic_int screenLayout;
+ std::atomic_int screenWidthDp;
+ std::atomic_int smallestScreenWidthDp;
+ std::atomic_int touchscreen;
+ std::atomic_int uiMode;
+} gConfiguration;
+
+/*
* Write a command to be executed by the GameActivity on the application main
* thread.
*/
@@ -342,6 +283,8 @@
ARect insetsState[GAMECOMMON_INSETS_TYPE_COUNT];
};
+static void readConfigurationValues(NativeCode *code, jobject javaConfig);
+
extern "C" void GameActivity_finish(GameActivity *activity) {
NativeCode *code = static_cast<NativeCode *>(activity);
write_work(code->mainWorkWrite, CMD_FINISH, 0);
@@ -462,10 +405,10 @@
// ------------------------------------------------------------------------
static thread_local std::string g_error_msg;
-static jlong initializeNativeCode_native(JNIEnv *env, jobject javaGameActivity,
- jstring internalDataDir, jstring obbDir,
- jstring externalDataDir, jobject jAssetMgr,
- jbyteArray savedState) {
+static jlong initializeNativeCode_native(
+ JNIEnv *env, jobject javaGameActivity, jstring internalDataDir,
+ jstring obbDir, jstring externalDataDir, jobject jAssetMgr,
+ jbyteArray savedState, jobject javaConfig) {
LOG_TRACE("initializeNativeCode_native");
NativeCode *code = NULL;
@@ -539,6 +482,9 @@
rawSavedState = env->GetByteArrayElements(savedState, NULL);
rawSavedSize = env->GetArrayLength(savedState);
}
+
+ readConfigurationValues(code, javaConfig);
+
GameActivity_onCreate(code, rawSavedState, rawSavedSize);
code->gameTextInput = GameTextInput_init(env, 0);
@@ -646,11 +592,50 @@
}
}
+static void readConfigurationValues(NativeCode *code, jobject javaConfig) {
+ gConfiguration.colorMode =
+ code->env->GetIntField(javaConfig, gConfigurationClassInfo.colorMode);
+ gConfiguration.densityDpi =
+ code->env->GetIntField(javaConfig, gConfigurationClassInfo.densityDpi);
+ gConfiguration.fontScale =
+ code->env->GetFloatField(javaConfig, gConfigurationClassInfo.fontScale);
+ gConfiguration.fontWeightAdjustment = code->env->GetIntField(
+ javaConfig, gConfigurationClassInfo.fontWeightAdjustment);
+ gConfiguration.hardKeyboardHidden = code->env->GetIntField(
+ javaConfig, gConfigurationClassInfo.hardKeyboardHidden);
+ gConfiguration.mcc =
+ code->env->GetIntField(javaConfig, gConfigurationClassInfo.mcc);
+ gConfiguration.mnc =
+ code->env->GetIntField(javaConfig, gConfigurationClassInfo.mnc);
+ gConfiguration.navigation =
+ code->env->GetIntField(javaConfig, gConfigurationClassInfo.navigation);
+ gConfiguration.navigationHidden = code->env->GetIntField(
+ javaConfig, gConfigurationClassInfo.navigationHidden);
+ gConfiguration.orientation =
+ code->env->GetIntField(javaConfig, gConfigurationClassInfo.orientation);
+ gConfiguration.screenHeightDp = code->env->GetIntField(
+ javaConfig, gConfigurationClassInfo.screenHeightDp);
+ gConfiguration.screenLayout = code->env->GetIntField(
+ javaConfig, gConfigurationClassInfo.screenLayout);
+ gConfiguration.screenWidthDp = code->env->GetIntField(
+ javaConfig, gConfigurationClassInfo.screenWidthDp);
+ gConfiguration.smallestScreenWidthDp = code->env->GetIntField(
+ javaConfig, gConfigurationClassInfo.smallestScreenWidthDp);
+ gConfiguration.touchscreen =
+ code->env->GetIntField(javaConfig, gConfigurationClassInfo.touchscreen);
+ gConfiguration.uiMode =
+ code->env->GetIntField(javaConfig, gConfigurationClassInfo.uiMode);
+
+ checkAndClearException(code->env, "Configuration.get");
+}
+
static void onConfigurationChanged_native(JNIEnv *env, jobject javaGameActivity,
- jlong handle) {
+ jlong handle, jobject javaNewConfig) {
LOG_TRACE("onConfigurationChanged_native");
if (handle != 0) {
NativeCode *code = (NativeCode *)handle;
+ readConfigurationValues(code, javaNewConfig);
+
if (code->callbacks.onConfigurationChanged != NULL) {
code->callbacks.onConfigurationChanged(code);
}
@@ -772,58 +757,6 @@
}
}
-static bool enabledAxes[GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT] = {
- /* AMOTION_EVENT_AXIS_X */ true,
- /* AMOTION_EVENT_AXIS_Y */ true,
- // Disable all other axes by default (they can be enabled using
- // `GameActivityPointerAxes_enableAxis`).
- false};
-
-extern "C" void GameActivityPointerAxes_enableAxis(int32_t axis) {
- if (axis < 0 || axis >= GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT) {
- return;
- }
-
- enabledAxes[axis] = true;
-}
-
-float GameActivityPointerAxes_getAxisValue(
- const GameActivityPointerAxes *pointerInfo, int32_t axis) {
- if (axis < 0 || axis >= GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT) {
- return 0;
- }
-
- if (!enabledAxes[axis]) {
- ALOGW("Axis %d must be enabled before it can be accessed.", axis);
- return 0;
- }
-
- return pointerInfo->axisValues[axis];
-}
-
-extern "C" void GameActivityPointerAxes_disableAxis(int32_t axis) {
- if (axis < 0 || axis >= GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT) {
- return;
- }
-
- enabledAxes[axis] = false;
-}
-
-float GameActivityMotionEvent_getHistoricalAxisValue(
- const GameActivityMotionEvent *event, int axis, int pointerIndex,
- int historyPos) {
- if (axis < 0 || axis >= GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT) {
- return 0;
- }
-
- if (!enabledAxes[axis]) {
- ALOGW("Axis %d must be enabled before it can be accessed.", axis);
- return 0;
- }
-
- return event->historicalAxisValues[event->pointerCount * historyPos + axis];
-}
-
extern "C" void GameActivity_setImeEditorInfo(GameActivity *activity,
int inputType, int actionId,
int imeOptions) {
@@ -832,295 +765,76 @@
actionId, imeOptions);
}
-static struct {
- jmethodID getDeviceId;
- jmethodID getSource;
- jmethodID getAction;
-
- jmethodID getEventTime;
- jmethodID getDownTime;
-
- jmethodID getFlags;
- jmethodID getMetaState;
-
- jmethodID getActionButton;
- jmethodID getButtonState;
- jmethodID getClassification;
- jmethodID getEdgeFlags;
-
- jmethodID getHistorySize;
- jmethodID getHistoricalEventTime;
-
- jmethodID getPointerCount;
- jmethodID getPointerId;
-
- jmethodID getToolType;
-
- jmethodID getRawX;
- jmethodID getRawY;
- jmethodID getXPrecision;
- jmethodID getYPrecision;
- jmethodID getAxisValue;
-
- jmethodID getHistoricalAxisValue;
-} gMotionEventClassInfo;
-
-extern "C" void GameActivityMotionEvent_destroy(
- GameActivityMotionEvent *c_event) {
- delete c_event->historicalAxisValues;
- delete c_event->historicalEventTimes;
+extern "C" int GameActivity_getColorMode(GameActivity *) {
+ return gConfiguration.colorMode;
}
-extern "C" void GameActivityMotionEvent_fromJava(
- JNIEnv *env, jobject motionEvent, GameActivityMotionEvent *out_event) {
- static bool gMotionEventClassInfoInitialized = false;
- if (!gMotionEventClassInfoInitialized) {
- int sdkVersion = GetSystemPropAsInt("ro.build.version.sdk");
- gMotionEventClassInfo = {0};
- jclass motionEventClass = env->FindClass("android/view/MotionEvent");
- gMotionEventClassInfo.getDeviceId =
- env->GetMethodID(motionEventClass, "getDeviceId", "()I");
- gMotionEventClassInfo.getSource =
- env->GetMethodID(motionEventClass, "getSource", "()I");
- gMotionEventClassInfo.getAction =
- env->GetMethodID(motionEventClass, "getAction", "()I");
- gMotionEventClassInfo.getEventTime =
- env->GetMethodID(motionEventClass, "getEventTime", "()J");
- gMotionEventClassInfo.getDownTime =
- env->GetMethodID(motionEventClass, "getDownTime", "()J");
- gMotionEventClassInfo.getFlags =
- env->GetMethodID(motionEventClass, "getFlags", "()I");
- gMotionEventClassInfo.getMetaState =
- env->GetMethodID(motionEventClass, "getMetaState", "()I");
- if (sdkVersion >= 23) {
- gMotionEventClassInfo.getActionButton =
- env->GetMethodID(motionEventClass, "getActionButton", "()I");
- }
- if (sdkVersion >= 14) {
- gMotionEventClassInfo.getButtonState =
- env->GetMethodID(motionEventClass, "getButtonState", "()I");
- }
- if (sdkVersion >= 29) {
- gMotionEventClassInfo.getClassification =
- env->GetMethodID(motionEventClass, "getClassification", "()I");
- }
- gMotionEventClassInfo.getEdgeFlags =
- env->GetMethodID(motionEventClass, "getEdgeFlags", "()I");
-
- gMotionEventClassInfo.getHistorySize =
- env->GetMethodID(motionEventClass, "getHistorySize", "()I");
- gMotionEventClassInfo.getHistoricalEventTime = env->GetMethodID(
- motionEventClass, "getHistoricalEventTime", "(I)J");
-
- gMotionEventClassInfo.getPointerCount =
- env->GetMethodID(motionEventClass, "getPointerCount", "()I");
- gMotionEventClassInfo.getPointerId =
- env->GetMethodID(motionEventClass, "getPointerId", "(I)I");
- gMotionEventClassInfo.getToolType =
- env->GetMethodID(motionEventClass, "getToolType", "(I)I");
- if (sdkVersion >= 29) {
- gMotionEventClassInfo.getRawX =
- env->GetMethodID(motionEventClass, "getRawX", "(I)F");
- gMotionEventClassInfo.getRawY =
- env->GetMethodID(motionEventClass, "getRawY", "(I)F");
- }
- gMotionEventClassInfo.getXPrecision =
- env->GetMethodID(motionEventClass, "getXPrecision", "()F");
- gMotionEventClassInfo.getYPrecision =
- env->GetMethodID(motionEventClass, "getYPrecision", "()F");
- gMotionEventClassInfo.getAxisValue =
- env->GetMethodID(motionEventClass, "getAxisValue", "(II)F");
-
- gMotionEventClassInfo.getHistoricalAxisValue = env->GetMethodID(
- motionEventClass, "getHistoricalAxisValue", "(III)F");
- gMotionEventClassInfoInitialized = true;
- }
-
- int pointerCount =
- env->CallIntMethod(motionEvent, gMotionEventClassInfo.getPointerCount);
- pointerCount =
- std::min(pointerCount, GAMEACTIVITY_MAX_NUM_POINTERS_IN_MOTION_EVENT);
- out_event->pointerCount = pointerCount;
- for (int i = 0; i < pointerCount; ++i) {
- out_event->pointers[i] = {
- /*id=*/env->CallIntMethod(motionEvent,
- gMotionEventClassInfo.getPointerId, i),
- /*toolType=*/
- env->CallIntMethod(motionEvent, gMotionEventClassInfo.getToolType,
- i),
- /*axisValues=*/{0},
- /*rawX=*/gMotionEventClassInfo.getRawX
- ? env->CallFloatMethod(motionEvent,
- gMotionEventClassInfo.getRawX, i)
- : 0,
- /*rawY=*/gMotionEventClassInfo.getRawY
- ? env->CallFloatMethod(motionEvent,
- gMotionEventClassInfo.getRawY, i)
- : 0,
- };
-
- for (int axisIndex = 0;
- axisIndex < GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT; ++axisIndex) {
- if (enabledAxes[axisIndex]) {
- out_event->pointers[i].axisValues[axisIndex] =
- env->CallFloatMethod(motionEvent,
- gMotionEventClassInfo.getAxisValue,
- axisIndex, i);
- }
- }
- }
-
- int historySize =
- env->CallIntMethod(motionEvent, gMotionEventClassInfo.getHistorySize);
- out_event->historySize = historySize;
- out_event->historicalAxisValues =
- new float[historySize * pointerCount *
- GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT];
- out_event->historicalEventTimes = new long[historySize];
-
- for (int historyIndex = 0; historyIndex < historySize; historyIndex++) {
- out_event->historicalEventTimes[historyIndex] = env->CallLongMethod(
- motionEvent, gMotionEventClassInfo.getHistoricalEventTime,
- historyIndex);
- for (int i = 0; i < pointerCount; ++i) {
- int pointerOffset = i * GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT;
- int historyAxisOffset = historyIndex * pointerCount *
- GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT;
- float *axisValues =
- &out_event
- ->historicalAxisValues[historyAxisOffset + pointerOffset];
- for (int axisIndex = 0;
- axisIndex < GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT;
- ++axisIndex) {
- if (enabledAxes[axisIndex]) {
- axisValues[axisIndex] = env->CallFloatMethod(
- motionEvent,
- gMotionEventClassInfo.getHistoricalAxisValue, axisIndex,
- i, historyIndex);
- }
- }
- }
- }
-
- out_event->deviceId =
- env->CallIntMethod(motionEvent, gMotionEventClassInfo.getDeviceId);
- out_event->source =
- env->CallIntMethod(motionEvent, gMotionEventClassInfo.getSource);
- out_event->action =
- env->CallIntMethod(motionEvent, gMotionEventClassInfo.getAction);
- out_event->eventTime =
- env->CallLongMethod(motionEvent, gMotionEventClassInfo.getEventTime) *
- 1000000;
- out_event->downTime =
- env->CallLongMethod(motionEvent, gMotionEventClassInfo.getDownTime) *
- 1000000;
- out_event->flags =
- env->CallIntMethod(motionEvent, gMotionEventClassInfo.getFlags);
- out_event->metaState =
- env->CallIntMethod(motionEvent, gMotionEventClassInfo.getMetaState);
- out_event->actionButton =
- gMotionEventClassInfo.getActionButton
- ? env->CallIntMethod(motionEvent,
- gMotionEventClassInfo.getActionButton)
- : 0;
- out_event->buttonState =
- gMotionEventClassInfo.getButtonState
- ? env->CallIntMethod(motionEvent,
- gMotionEventClassInfo.getButtonState)
- : 0;
- out_event->classification =
- gMotionEventClassInfo.getClassification
- ? env->CallIntMethod(motionEvent,
- gMotionEventClassInfo.getClassification)
- : 0;
- out_event->edgeFlags =
- env->CallIntMethod(motionEvent, gMotionEventClassInfo.getEdgeFlags);
- out_event->precisionX =
- env->CallFloatMethod(motionEvent, gMotionEventClassInfo.getXPrecision);
- out_event->precisionY =
- env->CallFloatMethod(motionEvent, gMotionEventClassInfo.getYPrecision);
+extern "C" int GameActivity_getDensityDpi(GameActivity *) {
+ return gConfiguration.densityDpi;
}
-static struct {
- jmethodID getDeviceId;
- jmethodID getSource;
- jmethodID getAction;
+extern "C" float GameActivity_getFontScale(GameActivity *) {
+ return gConfiguration.fontScale;
+}
- jmethodID getEventTime;
- jmethodID getDownTime;
+extern "C" int GameActivity_getFontWeightAdjustment(GameActivity *) {
+ return gConfiguration.fontWeightAdjustment;
+}
- jmethodID getFlags;
- jmethodID getMetaState;
+extern "C" int GameActivity_getHardKeyboardHidden(GameActivity *) {
+ return gConfiguration.hardKeyboardHidden;
+}
- jmethodID getModifiers;
- jmethodID getRepeatCount;
- jmethodID getKeyCode;
- jmethodID getScanCode;
- jmethodID getUnicodeChar;
-} gKeyEventClassInfo;
+extern "C" int GameActivity_getKeyboard(GameActivity *) {
+ return gConfiguration.keyboard;
+}
-extern "C" void GameActivityKeyEvent_fromJava(JNIEnv *env, jobject keyEvent,
- GameActivityKeyEvent *out_event) {
- static bool gKeyEventClassInfoInitialized = false;
- if (!gKeyEventClassInfoInitialized) {
- int sdkVersion = GetSystemPropAsInt("ro.build.version.sdk");
- gKeyEventClassInfo = {0};
- jclass keyEventClass = env->FindClass("android/view/KeyEvent");
- gKeyEventClassInfo.getDeviceId =
- env->GetMethodID(keyEventClass, "getDeviceId", "()I");
- gKeyEventClassInfo.getSource =
- env->GetMethodID(keyEventClass, "getSource", "()I");
- gKeyEventClassInfo.getAction =
- env->GetMethodID(keyEventClass, "getAction", "()I");
- gKeyEventClassInfo.getEventTime =
- env->GetMethodID(keyEventClass, "getEventTime", "()J");
- gKeyEventClassInfo.getDownTime =
- env->GetMethodID(keyEventClass, "getDownTime", "()J");
- gKeyEventClassInfo.getFlags =
- env->GetMethodID(keyEventClass, "getFlags", "()I");
- gKeyEventClassInfo.getMetaState =
- env->GetMethodID(keyEventClass, "getMetaState", "()I");
- if (sdkVersion >= 13) {
- gKeyEventClassInfo.getModifiers =
- env->GetMethodID(keyEventClass, "getModifiers", "()I");
- }
- gKeyEventClassInfo.getRepeatCount =
- env->GetMethodID(keyEventClass, "getRepeatCount", "()I");
- gKeyEventClassInfo.getKeyCode =
- env->GetMethodID(keyEventClass, "getKeyCode", "()I");
- gKeyEventClassInfo.getScanCode =
- env->GetMethodID(keyEventClass, "getScanCode", "()I");
- gKeyEventClassInfo.getUnicodeChar =
- env->GetMethodID(keyEventClass, "getUnicodeChar", "()I");
+extern "C" int GameActivity_getKeyboardHidden(GameActivity *) {
+ return gConfiguration.keyboardHidden;
+}
- gKeyEventClassInfoInitialized = true;
- }
+extern "C" int GameActivity_getMcc(GameActivity *) {
+ return gConfiguration.mcc;
+}
- *out_event = {
- /*deviceId=*/env->CallIntMethod(keyEvent,
- gKeyEventClassInfo.getDeviceId),
- /*source=*/env->CallIntMethod(keyEvent, gKeyEventClassInfo.getSource),
- /*action=*/env->CallIntMethod(keyEvent, gKeyEventClassInfo.getAction),
- // TODO: introduce a millisecondsToNanoseconds helper:
- /*eventTime=*/
- env->CallLongMethod(keyEvent, gKeyEventClassInfo.getEventTime) *
- 1000000,
- /*downTime=*/
- env->CallLongMethod(keyEvent, gKeyEventClassInfo.getDownTime) * 1000000,
- /*flags=*/env->CallIntMethod(keyEvent, gKeyEventClassInfo.getFlags),
- /*metaState=*/
- env->CallIntMethod(keyEvent, gKeyEventClassInfo.getMetaState),
- /*modifiers=*/gKeyEventClassInfo.getModifiers
- ? env->CallIntMethod(keyEvent, gKeyEventClassInfo.getModifiers)
- : 0,
- /*repeatCount=*/
- env->CallIntMethod(keyEvent, gKeyEventClassInfo.getRepeatCount),
- /*keyCode=*/
- env->CallIntMethod(keyEvent, gKeyEventClassInfo.getKeyCode),
- /*scanCode=*/
- env->CallIntMethod(keyEvent, gKeyEventClassInfo.getScanCode),
- /*unicodeChar=*/
- env->CallIntMethod(keyEvent, gKeyEventClassInfo.getUnicodeChar)};
+extern "C" int GameActivity_getMnc(GameActivity *) {
+ return gConfiguration.mnc;
+}
+
+extern "C" int GameActivity_getNavigation(GameActivity *) {
+ return gConfiguration.navigation;
+}
+
+extern "C" int GameActivity_getNavigationHidden(GameActivity *) {
+ return gConfiguration.navigationHidden;
+}
+
+extern "C" int GameActivity_getOrientation(GameActivity *) {
+ return gConfiguration.orientation;
+}
+
+extern "C" int GameActivity_getScreenHeightDp(GameActivity *) {
+ return gConfiguration.screenHeightDp;
+}
+
+extern "C" int GameActivity_getScreenLayout(GameActivity *) {
+ return gConfiguration.screenLayout;
+}
+
+extern "C" int GameActivity_getScreenWidthDp(GameActivity *) {
+ return gConfiguration.screenWidthDp;
+}
+
+extern "C" int GameActivity_getSmallestScreenWidthDp(GameActivity *) {
+ return gConfiguration.smallestScreenWidthDp;
+}
+
+extern "C" int GameActivity_getTouchscreen(GameActivity *) {
+ return gConfiguration.touchscreen;
+}
+
+extern "C" int GameActivity_getUIMode(GameActivity *) {
+ return gConfiguration.uiMode;
}
static bool onTouchEvent_native(JNIEnv *env, jobject javaGameActivity,
@@ -1209,10 +923,28 @@
GameTextInput_setInputConnection(code->gameTextInput, inputConnection);
}
+static void onContentRectChangedNative_native(JNIEnv *env, jobject activity,
+ jlong handle, jint x, jint y,
+ jint w, jint h) {
+ if (handle != 0) {
+ NativeCode *code = (NativeCode *)handle;
+
+ if (code->callbacks.onContentRectChanged != nullptr) {
+ ARect rect;
+ rect.left = x;
+ rect.top = y;
+ rect.right = x+w;
+ rect.bottom = y+h;
+ code->callbacks.onContentRectChanged(code, &rect);
+ }
+ }
+}
+
static const JNINativeMethod g_methods[] = {
{"initializeNativeCode",
"(Ljava/lang/String;Ljava/lang/String;"
- "Ljava/lang/String;Landroid/content/res/AssetManager;[B)J",
+ "Ljava/lang/String;Landroid/content/res/AssetManager;"
+ "[BLandroid/content/res/Configuration;)J",
(void *)initializeNativeCode_native},
{"getDlError", "()Ljava/lang/String;", (void *)getDlError_native},
{"terminateNativeCode", "(J)V", (void *)terminateNativeCode_native},
@@ -1221,7 +953,7 @@
{"onSaveInstanceStateNative", "(J)[B", (void *)onSaveInstanceState_native},
{"onPauseNative", "(J)V", (void *)onPause_native},
{"onStopNative", "(J)V", (void *)onStop_native},
- {"onConfigurationChangedNative", "(J)V",
+ {"onConfigurationChangedNative", "(JLandroid/content/res/Configuration;)V",
(void *)onConfigurationChanged_native},
{"onTrimMemoryNative", "(JI)V", (void *)onTrimMemory_native},
{"onWindowFocusChangedNative", "(JZ)V",
@@ -1246,13 +978,16 @@
{"setInputConnectionNative",
"(JLcom/google/androidgamesdk/gametextinput/InputConnection;)V",
(void *)setInputConnection_native},
+ {"onContentRectChangedNative", "(JIIII)V",
+ (void *)onContentRectChangedNative_native},
};
static const char *const kGameActivityPathName =
"com/google/androidgamesdk/GameActivity";
static const char *const kInsetsPathName = "androidx/core/graphics/Insets";
-
+static const char *const kConfigurationPathName =
+ "android/content/res/Configuration";
static const char *const kWindowInsetsCompatTypePathName =
"androidx/core/view/WindowInsetsCompat$Type";
@@ -1310,12 +1045,51 @@
"getWaterfallInsets", "()Landroidx/core/graphics/Insets;");
GET_METHOD_ID(gGameActivityClassInfo.setImeEditorInfoFields, activity_class,
"setImeEditorInfoFields", "(III)V");
+
jclass insets_class;
FIND_CLASS(insets_class, kInsetsPathName);
GET_FIELD_ID(gInsetsClassInfo.left, insets_class, "left", "I");
GET_FIELD_ID(gInsetsClassInfo.right, insets_class, "right", "I");
GET_FIELD_ID(gInsetsClassInfo.top, insets_class, "top", "I");
GET_FIELD_ID(gInsetsClassInfo.bottom, insets_class, "bottom", "I");
+
+ jclass configuration_class;
+ FIND_CLASS(configuration_class, kConfigurationPathName);
+ GET_FIELD_ID(gConfigurationClassInfo.colorMode, configuration_class,
+ "colorMode", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.densityDpi, configuration_class,
+ "densityDpi", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.fontScale, configuration_class,
+ "fontScale", "F");
+ GET_FIELD_ID(gConfigurationClassInfo.fontWeightAdjustment,
+ configuration_class, "fontWeightAdjustment", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.hardKeyboardHidden,
+ configuration_class, "hardKeyboardHidden", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.keyboard, configuration_class,
+ "keyboard", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.keyboardHidden, configuration_class,
+ "keyboardHidden", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.mcc, configuration_class, "mcc", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.mnc, configuration_class, "mnc", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.navigation, configuration_class,
+ "navigation", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.navigationHidden, configuration_class,
+ "navigationHidden", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.orientation, configuration_class,
+ "orientation", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.screenHeightDp, configuration_class,
+ "screenHeightDp", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.screenLayout, configuration_class,
+ "screenLayout", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.screenWidthDp, configuration_class,
+ "screenWidthDp", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.smallestScreenWidthDp,
+ configuration_class, "smallestScreenWidthDp", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.touchscreen, configuration_class,
+ "touchscreen", "I");
+ GET_FIELD_ID(gConfigurationClassInfo.uiMode, configuration_class, "uiMode",
+ "I");
+
jclass windowInsetsCompatType_class;
FIND_CLASS(windowInsetsCompatType_class, kWindowInsetsCompatTypePathName);
gWindowInsetsCompatTypeClassInfo.clazz =
@@ -1344,12 +1118,12 @@
extern "C" JNIEXPORT jlong JNICALL
Java_com_google_androidgamesdk_GameActivity_initializeNativeCode(
- JNIEnv *env, jobject javaGameActivity,
- jstring internalDataDir, jstring obbDir, jstring externalDataDir,
- jobject jAssetMgr, jbyteArray savedState) {
+ JNIEnv *env, jobject javaGameActivity, jstring internalDataDir,
+ jstring obbDir, jstring externalDataDir, jobject jAssetMgr,
+ jbyteArray savedState, jobject javaConfig) {
GameActivity_register(env);
jlong nativeCode = initializeNativeCode_native(
- env, javaGameActivity,internalDataDir, obbDir,
- externalDataDir, jAssetMgr, savedState);
+ env, javaGameActivity, internalDataDir, obbDir, externalDataDir,
+ jAssetMgr, savedState, javaConfig);
return nativeCode;
}
diff --git a/game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivity.h b/game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivity.h
index 31fd7ca..d43ab25 100644
--- a/game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivity.h
+++ b/game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivity.h
@@ -36,19 +36,21 @@
#include <stdint.h>
#include <sys/types.h>
+#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 1
-#define GAMEACTIVITY_MINOR_VERSION 2
-#define GAMEACTIVITY_BUGFIX_VERSION 2
-
-#define GAMEACTIVITY_PACKED_VERSION \
- ((GAMEACTIVITY_MAJOR_VERSION << 16) | (GAMEACTIVITY_MINOR_VERSION << 8) | \
- (GAMEACTIVITY_BUGFIX_VERSION))
+#define GAMEACTIVITY_MAJOR_VERSION 2
+#define GAMEACTIVITY_MINOR_VERSION 0
+#define GAMEACTIVITY_BUGFIX_VERSION 0
+#define GAMEACTIVITY_PACKED_VERSION \
+ ANDROID_GAMESDK_PACKED_VERSION(GAMEACTIVITY_MAJOR_VERSION, \
+ GAMEACTIVITY_MINOR_VERSION, \
+ GAMEACTIVITY_BUGFIX_VERSION)
/**
* {@link GameActivityCallbacks}
@@ -124,267 +126,6 @@
} GameActivity;
/**
- * The maximum number of axes supported in an Android MotionEvent.
- * See https://developer.android.com/ndk/reference/group/input.
- */
-#define GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT 48
-
-/**
- * \brief Describe information about a pointer, found in a
- * GameActivityMotionEvent.
- *
- * You can read values directly from this structure, or use helper functions
- * (`GameActivityPointerAxes_getX`, `GameActivityPointerAxes_getY` and
- * `GameActivityPointerAxes_getAxisValue`).
- *
- * The X axis and Y axis are enabled by default but any other axis that you want
- * to read **must** be enabled first, using
- * `GameActivityPointerAxes_enableAxis`.
- *
- * \see GameActivityMotionEvent
- */
-typedef struct GameActivityPointerAxes {
- int32_t id;
- int32_t toolType;
- float axisValues[GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT];
- float rawX;
- float rawY;
-} GameActivityPointerAxes;
-
-/** \brief Get the toolType of the pointer. */
-inline int32_t GameActivityPointerAxes_getToolType(
- const GameActivityPointerAxes* pointerInfo) {
- return pointerInfo->toolType;
-}
-
-/** \brief Get the current X coordinate of the pointer. */
-inline float GameActivityPointerAxes_getX(
- const GameActivityPointerAxes* pointerInfo) {
- return pointerInfo->axisValues[AMOTION_EVENT_AXIS_X];
-}
-
-/** \brief Get the current Y coordinate of the pointer. */
-inline float GameActivityPointerAxes_getY(
- const GameActivityPointerAxes* pointerInfo) {
- return pointerInfo->axisValues[AMOTION_EVENT_AXIS_Y];
-}
-
-/**
- * \brief Enable the specified axis, so that its value is reported in the
- * GameActivityPointerAxes structures stored in a motion event.
- *
- * You must enable any axis that you want to read, apart from
- * `AMOTION_EVENT_AXIS_X` and `AMOTION_EVENT_AXIS_Y` that are enabled by
- * default.
- *
- * If the axis index is out of range, nothing is done.
- */
-void GameActivityPointerAxes_enableAxis(int32_t axis);
-
-/**
- * \brief Disable the specified axis. Its value won't be reported in the
- * GameActivityPointerAxes structures stored in a motion event anymore.
- *
- * Apart from X and Y, any axis that you want to read **must** be enabled first,
- * using `GameActivityPointerAxes_enableAxis`.
- *
- * If the axis index is out of range, nothing is done.
- */
-void GameActivityPointerAxes_disableAxis(int32_t axis);
-
-/**
- * \brief Get the value of the requested axis.
- *
- * Apart from X and Y, any axis that you want to read **must** be enabled first,
- * using `GameActivityPointerAxes_enableAxis`.
- *
- * Find the valid enums for the axis (`AMOTION_EVENT_AXIS_X`,
- * `AMOTION_EVENT_AXIS_Y`, `AMOTION_EVENT_AXIS_PRESSURE`...)
- * in https://developer.android.com/ndk/reference/group/input.
- *
- * @param pointerInfo The structure containing information about the pointer,
- * obtained from GameActivityMotionEvent.
- * @param axis The axis to get the value from
- * @return The value of the axis, or 0 if the axis is invalid or was not
- * enabled.
- */
-float GameActivityPointerAxes_getAxisValue(
- const GameActivityPointerAxes* pointerInfo, int32_t axis);
-
-inline float GameActivityPointerAxes_getPressure(
- const GameActivityPointerAxes* pointerInfo) {
- return GameActivityPointerAxes_getAxisValue(pointerInfo,
- AMOTION_EVENT_AXIS_PRESSURE);
-}
-
-inline float GameActivityPointerAxes_getSize(
- const GameActivityPointerAxes* pointerInfo) {
- return GameActivityPointerAxes_getAxisValue(pointerInfo,
- AMOTION_EVENT_AXIS_SIZE);
-}
-
-inline float GameActivityPointerAxes_getTouchMajor(
- const GameActivityPointerAxes* pointerInfo) {
- return GameActivityPointerAxes_getAxisValue(pointerInfo,
- AMOTION_EVENT_AXIS_TOUCH_MAJOR);
-}
-
-inline float GameActivityPointerAxes_getTouchMinor(
- const GameActivityPointerAxes* pointerInfo) {
- return GameActivityPointerAxes_getAxisValue(pointerInfo,
- AMOTION_EVENT_AXIS_TOUCH_MINOR);
-}
-
-inline float GameActivityPointerAxes_getToolMajor(
- const GameActivityPointerAxes* pointerInfo) {
- return GameActivityPointerAxes_getAxisValue(pointerInfo,
- AMOTION_EVENT_AXIS_TOOL_MAJOR);
-}
-
-inline float GameActivityPointerAxes_getToolMinor(
- const GameActivityPointerAxes* pointerInfo) {
- return GameActivityPointerAxes_getAxisValue(pointerInfo,
- AMOTION_EVENT_AXIS_TOOL_MINOR);
-}
-
-inline float GameActivityPointerAxes_getOrientation(
- const GameActivityPointerAxes* pointerInfo) {
- return GameActivityPointerAxes_getAxisValue(pointerInfo,
- AMOTION_EVENT_AXIS_ORIENTATION);
-}
-
-/**
- * The maximum number of pointers returned inside a motion event.
- */
-#if (defined GAMEACTIVITY_MAX_NUM_POINTERS_IN_MOTION_EVENT_OVERRIDE)
-#define GAMEACTIVITY_MAX_NUM_POINTERS_IN_MOTION_EVENT \
- GAMEACTIVITY_MAX_NUM_POINTERS_IN_MOTION_EVENT_OVERRIDE
-#else
-#define GAMEACTIVITY_MAX_NUM_POINTERS_IN_MOTION_EVENT 8
-#endif
-
-/**
- * \brief Describe a motion event that happened on the GameActivity SurfaceView.
- *
- * This is 1:1 mapping to the information contained in a Java `MotionEvent`
- * (see https://developer.android.com/reference/android/view/MotionEvent).
- */
-typedef struct GameActivityMotionEvent {
- int32_t deviceId;
- int32_t source;
- int32_t action;
-
- int64_t eventTime;
- int64_t downTime;
-
- int32_t flags;
- int32_t metaState;
-
- int32_t actionButton;
- int32_t buttonState;
- int32_t classification;
- int32_t edgeFlags;
-
- uint32_t pointerCount;
- GameActivityPointerAxes
- pointers[GAMEACTIVITY_MAX_NUM_POINTERS_IN_MOTION_EVENT];
-
- int historySize;
- long* historicalEventTimes;
- float* historicalAxisValues;
-
- float precisionX;
- float precisionY;
-} GameActivityMotionEvent;
-
-/**
- * \brief Describe a key event that happened on the GameActivity SurfaceView.
- *
- * This is 1:1 mapping to the information contained in a Java `KeyEvent`
- * (see https://developer.android.com/reference/android/view/KeyEvent).
- */
-typedef struct GameActivityKeyEvent {
- int32_t deviceId;
- int32_t source;
- int32_t action;
-
- int64_t eventTime;
- int64_t downTime;
-
- int32_t flags;
- int32_t metaState;
-
- int32_t modifiers;
- int32_t repeatCount;
- int32_t keyCode;
- int32_t scanCode;
- int32_t unicodeChar;
-} GameActivityKeyEvent;
-
-float GameActivityMotionEvent_getHistoricalAxisValue(
- const GameActivityMotionEvent* event, int axis, int pointerIndex,
- int historyPos);
-
-inline int GameActivityMotionEvent_getHistorySize(
- const GameActivityMotionEvent* event) {
- return event->historySize;
-}
-
-inline float GameActivityMotionEvent_getHistoricalX(
- const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
- return GameActivityMotionEvent_getHistoricalAxisValue(
- event, AMOTION_EVENT_AXIS_X, pointerIndex, historyPos);
-}
-
-inline float GameActivityMotionEvent_getHistoricalY(
- const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
- return GameActivityMotionEvent_getHistoricalAxisValue(
- event, AMOTION_EVENT_AXIS_Y, pointerIndex, historyPos);
-}
-
-inline float GameActivityMotionEvent_getHistoricalPressure(
- const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
- return GameActivityMotionEvent_getHistoricalAxisValue(
- event, AMOTION_EVENT_AXIS_PRESSURE, pointerIndex, historyPos);
-}
-
-inline float GameActivityMotionEvent_getHistoricalSize(
- const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
- return GameActivityMotionEvent_getHistoricalAxisValue(
- event, AMOTION_EVENT_AXIS_SIZE, pointerIndex, historyPos);
-}
-
-inline float GameActivityMotionEvent_getHistoricalTouchMajor(
- const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
- return GameActivityMotionEvent_getHistoricalAxisValue(
- event, AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex, historyPos);
-}
-
-inline float GameActivityMotionEvent_getHistoricalTouchMinor(
- const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
- return GameActivityMotionEvent_getHistoricalAxisValue(
- event, AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex, historyPos);
-}
-
-inline float GameActivityMotionEvent_getHistoricalToolMajor(
- const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
- return GameActivityMotionEvent_getHistoricalAxisValue(
- event, AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex, historyPos);
-}
-
-inline float GameActivityMotionEvent_getHistoricalToolMinor(
- const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
- return GameActivityMotionEvent_getHistoricalAxisValue(
- event, AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex, historyPos);
-}
-
-inline float GameActivityMotionEvent_getHistoricalOrientation(
- const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
- return GameActivityMotionEvent_getHistoricalAxisValue(
- event, AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex, historyPos);
-}
-
-/**
* A function the user should call from their callback with the data, its length
* and the library- supplied context.
*/
@@ -530,35 +271,14 @@
* 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;
-/** \brief Handle the freeing of the GameActivityMotionEvent struct. */
-void GameActivityMotionEvent_destroy(GameActivityMotionEvent* c_event);
-
-/**
- * \brief Convert a Java `MotionEvent` to a `GameActivityMotionEvent`.
- *
- * This is done automatically by the GameActivity: see `onTouchEvent` to set
- * a callback to consume the received events.
- * This function can be used if you re-implement events handling in your own
- * activity.
- * Ownership of out_event is maintained by the caller.
- */
-void GameActivityMotionEvent_fromJava(JNIEnv* env, jobject motionEvent,
- GameActivityMotionEvent* out_event);
-
-/**
- * \brief Convert a Java `KeyEvent` to a `GameActivityKeyEvent`.
- *
- * This is done automatically by the GameActivity: see `onKeyUp` and `onKeyDown`
- * to set a callback to consume the received events.
- * This function can be used if you re-implement events handling in your own
- * activity.
- * Ownership of out_event is maintained by the caller.
- */
-void GameActivityKeyEvent_fromJava(JNIEnv* env, jobject motionEvent,
- GameActivityKeyEvent* out_event);
-
/**
* 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
@@ -883,6 +603,30 @@
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
diff --git a/game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivityEvents.cpp b/game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivityEvents.cpp
new file mode 100644
index 0000000..2cf2356
--- /dev/null
+++ b/game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivityEvents.cpp
@@ -0,0 +1,401 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+
+#include "GameActivityEvents.h"
+
+#include <sys/system_properties.h>
+
+#include <string>
+
+#include "GameActivityLog.h"
+
+// TODO(b/187147166): these functions were extracted from the Game SDK
+// (gamesdk/src/common/system_utils.h). system_utils.h/cpp should be used
+// instead.
+namespace {
+
+std::string getSystemPropViaGet(const char *key,
+ const char *default_value = "") {
+ char buffer[PROP_VALUE_MAX + 1] = ""; // +1 for terminator
+ int bufferLen = __system_property_get(key, buffer);
+ if (bufferLen > 0)
+ return buffer;
+ else
+ return "";
+}
+
+std::string GetSystemProp(const char *key, const char *default_value = "") {
+ return getSystemPropViaGet(key, default_value);
+}
+
+int GetSystemPropAsInt(const char *key, int default_value = 0) {
+ std::string prop = GetSystemProp(key);
+ return prop == "" ? default_value : strtoll(prop.c_str(), nullptr, 10);
+}
+
+} // anonymous namespace
+
+#ifndef NELEM
+#define NELEM(x) ((int)(sizeof(x) / sizeof((x)[0])))
+#endif
+
+static bool enabledAxes[GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT] = {
+ /* AMOTION_EVENT_AXIS_X */ true,
+ /* AMOTION_EVENT_AXIS_Y */ true,
+ // Disable all other axes by default (they can be enabled using
+ // `GameActivityPointerAxes_enableAxis`).
+ false};
+
+extern "C" void GameActivityPointerAxes_enableAxis(int32_t axis) {
+ if (axis < 0 || axis >= GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT) {
+ return;
+ }
+
+ enabledAxes[axis] = true;
+}
+
+float GameActivityPointerAxes_getAxisValue(
+ const GameActivityPointerAxes *pointerInfo, int32_t axis) {
+ if (axis < 0 || axis >= GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT) {
+ return 0;
+ }
+
+ if (!enabledAxes[axis]) {
+ ALOGW("Axis %d must be enabled before it can be accessed.", axis);
+ return 0;
+ }
+
+ return pointerInfo->axisValues[axis];
+}
+
+extern "C" void GameActivityPointerAxes_disableAxis(int32_t axis) {
+ if (axis < 0 || axis >= GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT) {
+ return;
+ }
+
+ enabledAxes[axis] = false;
+}
+
+float GameActivityMotionEvent_getHistoricalAxisValue(
+ const GameActivityMotionEvent *event, int axis, int pointerIndex,
+ int historyPos) {
+ if (axis < 0 || axis >= GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT) {
+ return 0;
+ }
+
+ if (!enabledAxes[axis]) {
+ ALOGW("Axis %d must be enabled before it can be accessed.", axis);
+ return 0;
+ }
+
+ return event->historicalAxisValues[event->pointerCount * historyPos + axis];
+}
+
+static struct {
+ jmethodID getDeviceId;
+ jmethodID getSource;
+ jmethodID getAction;
+
+ jmethodID getEventTime;
+ jmethodID getDownTime;
+
+ jmethodID getFlags;
+ jmethodID getMetaState;
+
+ jmethodID getActionButton;
+ jmethodID getButtonState;
+ jmethodID getClassification;
+ jmethodID getEdgeFlags;
+
+ jmethodID getHistorySize;
+ jmethodID getHistoricalEventTime;
+
+ jmethodID getPointerCount;
+ jmethodID getPointerId;
+
+ jmethodID getToolType;
+
+ jmethodID getRawX;
+ jmethodID getRawY;
+ jmethodID getXPrecision;
+ jmethodID getYPrecision;
+ jmethodID getAxisValue;
+
+ jmethodID getHistoricalAxisValue;
+} gMotionEventClassInfo;
+
+extern "C" void GameActivityMotionEvent_destroy(
+ GameActivityMotionEvent *c_event) {
+ delete c_event->historicalAxisValues;
+ delete c_event->historicalEventTimesMillis;
+ delete c_event->historicalEventTimesNanos;
+}
+
+extern "C" void GameActivityMotionEvent_fromJava(
+ JNIEnv *env, jobject motionEvent, GameActivityMotionEvent *out_event) {
+ static bool gMotionEventClassInfoInitialized = false;
+ if (!gMotionEventClassInfoInitialized) {
+ int sdkVersion = GetSystemPropAsInt("ro.build.version.sdk");
+ gMotionEventClassInfo = {0};
+ jclass motionEventClass = env->FindClass("android/view/MotionEvent");
+ gMotionEventClassInfo.getDeviceId =
+ env->GetMethodID(motionEventClass, "getDeviceId", "()I");
+ gMotionEventClassInfo.getSource =
+ env->GetMethodID(motionEventClass, "getSource", "()I");
+ gMotionEventClassInfo.getAction =
+ env->GetMethodID(motionEventClass, "getAction", "()I");
+ gMotionEventClassInfo.getEventTime =
+ env->GetMethodID(motionEventClass, "getEventTime", "()J");
+ gMotionEventClassInfo.getDownTime =
+ env->GetMethodID(motionEventClass, "getDownTime", "()J");
+ gMotionEventClassInfo.getFlags =
+ env->GetMethodID(motionEventClass, "getFlags", "()I");
+ gMotionEventClassInfo.getMetaState =
+ env->GetMethodID(motionEventClass, "getMetaState", "()I");
+ if (sdkVersion >= 23) {
+ gMotionEventClassInfo.getActionButton =
+ env->GetMethodID(motionEventClass, "getActionButton", "()I");
+ }
+ if (sdkVersion >= 14) {
+ gMotionEventClassInfo.getButtonState =
+ env->GetMethodID(motionEventClass, "getButtonState", "()I");
+ }
+ if (sdkVersion >= 29) {
+ gMotionEventClassInfo.getClassification =
+ env->GetMethodID(motionEventClass, "getClassification", "()I");
+ }
+ gMotionEventClassInfo.getEdgeFlags =
+ env->GetMethodID(motionEventClass, "getEdgeFlags", "()I");
+
+ gMotionEventClassInfo.getHistorySize =
+ env->GetMethodID(motionEventClass, "getHistorySize", "()I");
+ gMotionEventClassInfo.getHistoricalEventTime = env->GetMethodID(
+ motionEventClass, "getHistoricalEventTime", "(I)J");
+
+ gMotionEventClassInfo.getPointerCount =
+ env->GetMethodID(motionEventClass, "getPointerCount", "()I");
+ gMotionEventClassInfo.getPointerId =
+ env->GetMethodID(motionEventClass, "getPointerId", "(I)I");
+ gMotionEventClassInfo.getToolType =
+ env->GetMethodID(motionEventClass, "getToolType", "(I)I");
+ if (sdkVersion >= 29) {
+ gMotionEventClassInfo.getRawX =
+ env->GetMethodID(motionEventClass, "getRawX", "(I)F");
+ gMotionEventClassInfo.getRawY =
+ env->GetMethodID(motionEventClass, "getRawY", "(I)F");
+ }
+ gMotionEventClassInfo.getXPrecision =
+ env->GetMethodID(motionEventClass, "getXPrecision", "()F");
+ gMotionEventClassInfo.getYPrecision =
+ env->GetMethodID(motionEventClass, "getYPrecision", "()F");
+ gMotionEventClassInfo.getAxisValue =
+ env->GetMethodID(motionEventClass, "getAxisValue", "(II)F");
+
+ gMotionEventClassInfo.getHistoricalAxisValue = env->GetMethodID(
+ motionEventClass, "getHistoricalAxisValue", "(III)F");
+ gMotionEventClassInfoInitialized = true;
+ }
+
+ int pointerCount =
+ env->CallIntMethod(motionEvent, gMotionEventClassInfo.getPointerCount);
+ pointerCount =
+ std::min(pointerCount, GAMEACTIVITY_MAX_NUM_POINTERS_IN_MOTION_EVENT);
+ out_event->pointerCount = pointerCount;
+ for (int i = 0; i < pointerCount; ++i) {
+ out_event->pointers[i] = {
+ /*id=*/env->CallIntMethod(motionEvent,
+ gMotionEventClassInfo.getPointerId, i),
+ /*toolType=*/
+ env->CallIntMethod(motionEvent, gMotionEventClassInfo.getToolType,
+ i),
+ /*axisValues=*/{0},
+ /*rawX=*/gMotionEventClassInfo.getRawX
+ ? env->CallFloatMethod(motionEvent,
+ gMotionEventClassInfo.getRawX, i)
+ : 0,
+ /*rawY=*/gMotionEventClassInfo.getRawY
+ ? env->CallFloatMethod(motionEvent,
+ gMotionEventClassInfo.getRawY, i)
+ : 0,
+ };
+
+ for (int axisIndex = 0;
+ axisIndex < GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT; ++axisIndex) {
+ if (enabledAxes[axisIndex]) {
+ out_event->pointers[i].axisValues[axisIndex] =
+ env->CallFloatMethod(motionEvent,
+ gMotionEventClassInfo.getAxisValue,
+ axisIndex, i);
+ }
+ }
+ }
+
+ int historySize =
+ env->CallIntMethod(motionEvent, gMotionEventClassInfo.getHistorySize);
+ out_event->historySize = historySize;
+ out_event->historicalAxisValues =
+ new float[historySize * pointerCount *
+ GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT];
+ out_event->historicalEventTimesMillis = new long[historySize];
+ out_event->historicalEventTimesNanos = new long[historySize];
+
+ for (int historyIndex = 0; historyIndex < historySize; historyIndex++) {
+ out_event->historicalEventTimesMillis[historyIndex] =
+ env->CallLongMethod(motionEvent,
+ gMotionEventClassInfo.getHistoricalEventTime,
+ historyIndex);
+ out_event->historicalEventTimesNanos[historyIndex] =
+ out_event->historicalEventTimesMillis[historyIndex] * 1000000;
+ for (int i = 0; i < pointerCount; ++i) {
+ int pointerOffset = i * GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT;
+ int historyAxisOffset = historyIndex * pointerCount *
+ GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT;
+ float *axisValues =
+ &out_event
+ ->historicalAxisValues[historyAxisOffset + pointerOffset];
+ for (int axisIndex = 0;
+ axisIndex < GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT;
+ ++axisIndex) {
+ if (enabledAxes[axisIndex]) {
+ axisValues[axisIndex] = env->CallFloatMethod(
+ motionEvent,
+ gMotionEventClassInfo.getHistoricalAxisValue, axisIndex,
+ i, historyIndex);
+ }
+ }
+ }
+ }
+
+ out_event->deviceId =
+ env->CallIntMethod(motionEvent, gMotionEventClassInfo.getDeviceId);
+ out_event->source =
+ env->CallIntMethod(motionEvent, gMotionEventClassInfo.getSource);
+ out_event->action =
+ env->CallIntMethod(motionEvent, gMotionEventClassInfo.getAction);
+ out_event->eventTime =
+ env->CallLongMethod(motionEvent, gMotionEventClassInfo.getEventTime) *
+ 1000000;
+ out_event->downTime =
+ env->CallLongMethod(motionEvent, gMotionEventClassInfo.getDownTime) *
+ 1000000;
+ out_event->flags =
+ env->CallIntMethod(motionEvent, gMotionEventClassInfo.getFlags);
+ out_event->metaState =
+ env->CallIntMethod(motionEvent, gMotionEventClassInfo.getMetaState);
+ out_event->actionButton =
+ gMotionEventClassInfo.getActionButton
+ ? env->CallIntMethod(motionEvent,
+ gMotionEventClassInfo.getActionButton)
+ : 0;
+ out_event->buttonState =
+ gMotionEventClassInfo.getButtonState
+ ? env->CallIntMethod(motionEvent,
+ gMotionEventClassInfo.getButtonState)
+ : 0;
+ out_event->classification =
+ gMotionEventClassInfo.getClassification
+ ? env->CallIntMethod(motionEvent,
+ gMotionEventClassInfo.getClassification)
+ : 0;
+ out_event->edgeFlags =
+ env->CallIntMethod(motionEvent, gMotionEventClassInfo.getEdgeFlags);
+ out_event->precisionX =
+ env->CallFloatMethod(motionEvent, gMotionEventClassInfo.getXPrecision);
+ out_event->precisionY =
+ env->CallFloatMethod(motionEvent, gMotionEventClassInfo.getYPrecision);
+}
+
+static struct {
+ jmethodID getDeviceId;
+ jmethodID getSource;
+ jmethodID getAction;
+
+ jmethodID getEventTime;
+ jmethodID getDownTime;
+
+ jmethodID getFlags;
+ jmethodID getMetaState;
+
+ jmethodID getModifiers;
+ jmethodID getRepeatCount;
+ jmethodID getKeyCode;
+ jmethodID getScanCode;
+ jmethodID getUnicodeChar;
+} gKeyEventClassInfo;
+
+extern "C" void GameActivityKeyEvent_fromJava(JNIEnv *env, jobject keyEvent,
+ GameActivityKeyEvent *out_event) {
+ static bool gKeyEventClassInfoInitialized = false;
+ if (!gKeyEventClassInfoInitialized) {
+ int sdkVersion = GetSystemPropAsInt("ro.build.version.sdk");
+ gKeyEventClassInfo = {0};
+ jclass keyEventClass = env->FindClass("android/view/KeyEvent");
+ gKeyEventClassInfo.getDeviceId =
+ env->GetMethodID(keyEventClass, "getDeviceId", "()I");
+ gKeyEventClassInfo.getSource =
+ env->GetMethodID(keyEventClass, "getSource", "()I");
+ gKeyEventClassInfo.getAction =
+ env->GetMethodID(keyEventClass, "getAction", "()I");
+ gKeyEventClassInfo.getEventTime =
+ env->GetMethodID(keyEventClass, "getEventTime", "()J");
+ gKeyEventClassInfo.getDownTime =
+ env->GetMethodID(keyEventClass, "getDownTime", "()J");
+ gKeyEventClassInfo.getFlags =
+ env->GetMethodID(keyEventClass, "getFlags", "()I");
+ gKeyEventClassInfo.getMetaState =
+ env->GetMethodID(keyEventClass, "getMetaState", "()I");
+ if (sdkVersion >= 13) {
+ gKeyEventClassInfo.getModifiers =
+ env->GetMethodID(keyEventClass, "getModifiers", "()I");
+ }
+ gKeyEventClassInfo.getRepeatCount =
+ env->GetMethodID(keyEventClass, "getRepeatCount", "()I");
+ gKeyEventClassInfo.getKeyCode =
+ env->GetMethodID(keyEventClass, "getKeyCode", "()I");
+ gKeyEventClassInfo.getScanCode =
+ env->GetMethodID(keyEventClass, "getScanCode", "()I");
+ gKeyEventClassInfo.getUnicodeChar =
+ env->GetMethodID(keyEventClass, "getUnicodeChar", "()I");
+
+ gKeyEventClassInfoInitialized = true;
+ }
+
+ *out_event = {
+ /*deviceId=*/env->CallIntMethod(keyEvent,
+ gKeyEventClassInfo.getDeviceId),
+ /*source=*/env->CallIntMethod(keyEvent, gKeyEventClassInfo.getSource),
+ /*action=*/env->CallIntMethod(keyEvent, gKeyEventClassInfo.getAction),
+ // TODO: introduce a millisecondsToNanoseconds helper:
+ /*eventTime=*/
+ env->CallLongMethod(keyEvent, gKeyEventClassInfo.getEventTime) *
+ 1000000,
+ /*downTime=*/
+ env->CallLongMethod(keyEvent, gKeyEventClassInfo.getDownTime) * 1000000,
+ /*flags=*/env->CallIntMethod(keyEvent, gKeyEventClassInfo.getFlags),
+ /*metaState=*/
+ env->CallIntMethod(keyEvent, gKeyEventClassInfo.getMetaState),
+ /*modifiers=*/gKeyEventClassInfo.getModifiers
+ ? env->CallIntMethod(keyEvent, gKeyEventClassInfo.getModifiers)
+ : 0,
+ /*repeatCount=*/
+ env->CallIntMethod(keyEvent, gKeyEventClassInfo.getRepeatCount),
+ /*keyCode=*/
+ env->CallIntMethod(keyEvent, gKeyEventClassInfo.getKeyCode),
+ /*scanCode=*/
+ env->CallIntMethod(keyEvent, gKeyEventClassInfo.getScanCode),
+ /*unicodeChar=*/
+ env->CallIntMethod(keyEvent, gKeyEventClassInfo.getUnicodeChar)};
+}
diff --git a/game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivityEvents.h b/game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivityEvents.h
new file mode 100644
index 0000000..4149dda
--- /dev/null
+++ b/game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivityEvents.h
@@ -0,0 +1,336 @@
+/*
+ * Copyright (C) 2022 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 Events
+ * The interface to use Game Activity Events.
+ * @{
+ */
+
+/**
+ * @file GameActivityEvents.h
+ */
+#ifndef ANDROID_GAME_SDK_GAME_ACTIVITY_EVENTS_H
+#define ANDROID_GAME_SDK_GAME_ACTIVITY_EVENTS_H
+
+#include <android/input.h>
+#include <jni.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * The maximum number of axes supported in an Android MotionEvent.
+ * See https://developer.android.com/ndk/reference/group/input.
+ */
+#define GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT 48
+
+/**
+ * \brief Describe information about a pointer, found in a
+ * GameActivityMotionEvent.
+ *
+ * You can read values directly from this structure, or use helper functions
+ * (`GameActivityPointerAxes_getX`, `GameActivityPointerAxes_getY` and
+ * `GameActivityPointerAxes_getAxisValue`).
+ *
+ * The X axis and Y axis are enabled by default but any other axis that you want
+ * to read **must** be enabled first, using
+ * `GameActivityPointerAxes_enableAxis`.
+ *
+ * \see GameActivityMotionEvent
+ */
+typedef struct GameActivityPointerAxes {
+ int32_t id;
+ int32_t toolType;
+ float axisValues[GAME_ACTIVITY_POINTER_INFO_AXIS_COUNT];
+ float rawX;
+ float rawY;
+} GameActivityPointerAxes;
+
+/** \brief Get the toolType of the pointer. */
+inline int32_t GameActivityPointerAxes_getToolType(
+ const GameActivityPointerAxes* pointerInfo) {
+ return pointerInfo->toolType;
+}
+
+/** \brief Get the current X coordinate of the pointer. */
+inline float GameActivityPointerAxes_getX(
+ const GameActivityPointerAxes* pointerInfo) {
+ return pointerInfo->axisValues[AMOTION_EVENT_AXIS_X];
+}
+
+/** \brief Get the current Y coordinate of the pointer. */
+inline float GameActivityPointerAxes_getY(
+ const GameActivityPointerAxes* pointerInfo) {
+ return pointerInfo->axisValues[AMOTION_EVENT_AXIS_Y];
+}
+
+/**
+ * \brief Enable the specified axis, so that its value is reported in the
+ * GameActivityPointerAxes structures stored in a motion event.
+ *
+ * You must enable any axis that you want to read, apart from
+ * `AMOTION_EVENT_AXIS_X` and `AMOTION_EVENT_AXIS_Y` that are enabled by
+ * default.
+ *
+ * If the axis index is out of range, nothing is done.
+ */
+void GameActivityPointerAxes_enableAxis(int32_t axis);
+
+/**
+ * \brief Disable the specified axis. Its value won't be reported in the
+ * GameActivityPointerAxes structures stored in a motion event anymore.
+ *
+ * Apart from X and Y, any axis that you want to read **must** be enabled first,
+ * using `GameActivityPointerAxes_enableAxis`.
+ *
+ * If the axis index is out of range, nothing is done.
+ */
+void GameActivityPointerAxes_disableAxis(int32_t axis);
+
+/**
+ * \brief Get the value of the requested axis.
+ *
+ * Apart from X and Y, any axis that you want to read **must** be enabled first,
+ * using `GameActivityPointerAxes_enableAxis`.
+ *
+ * Find the valid enums for the axis (`AMOTION_EVENT_AXIS_X`,
+ * `AMOTION_EVENT_AXIS_Y`, `AMOTION_EVENT_AXIS_PRESSURE`...)
+ * in https://developer.android.com/ndk/reference/group/input.
+ *
+ * @param pointerInfo The structure containing information about the pointer,
+ * obtained from GameActivityMotionEvent.
+ * @param axis The axis to get the value from
+ * @return The value of the axis, or 0 if the axis is invalid or was not
+ * enabled.
+ */
+float GameActivityPointerAxes_getAxisValue(
+ const GameActivityPointerAxes* pointerInfo, int32_t axis);
+
+inline float GameActivityPointerAxes_getPressure(
+ const GameActivityPointerAxes* pointerInfo) {
+ return GameActivityPointerAxes_getAxisValue(pointerInfo,
+ AMOTION_EVENT_AXIS_PRESSURE);
+}
+
+inline float GameActivityPointerAxes_getSize(
+ const GameActivityPointerAxes* pointerInfo) {
+ return GameActivityPointerAxes_getAxisValue(pointerInfo,
+ AMOTION_EVENT_AXIS_SIZE);
+}
+
+inline float GameActivityPointerAxes_getTouchMajor(
+ const GameActivityPointerAxes* pointerInfo) {
+ return GameActivityPointerAxes_getAxisValue(pointerInfo,
+ AMOTION_EVENT_AXIS_TOUCH_MAJOR);
+}
+
+inline float GameActivityPointerAxes_getTouchMinor(
+ const GameActivityPointerAxes* pointerInfo) {
+ return GameActivityPointerAxes_getAxisValue(pointerInfo,
+ AMOTION_EVENT_AXIS_TOUCH_MINOR);
+}
+
+inline float GameActivityPointerAxes_getToolMajor(
+ const GameActivityPointerAxes* pointerInfo) {
+ return GameActivityPointerAxes_getAxisValue(pointerInfo,
+ AMOTION_EVENT_AXIS_TOOL_MAJOR);
+}
+
+inline float GameActivityPointerAxes_getToolMinor(
+ const GameActivityPointerAxes* pointerInfo) {
+ return GameActivityPointerAxes_getAxisValue(pointerInfo,
+ AMOTION_EVENT_AXIS_TOOL_MINOR);
+}
+
+inline float GameActivityPointerAxes_getOrientation(
+ const GameActivityPointerAxes* pointerInfo) {
+ return GameActivityPointerAxes_getAxisValue(pointerInfo,
+ AMOTION_EVENT_AXIS_ORIENTATION);
+}
+
+/**
+ * The maximum number of pointers returned inside a motion event.
+ */
+#if (defined GAMEACTIVITY_MAX_NUM_POINTERS_IN_MOTION_EVENT_OVERRIDE)
+#define GAMEACTIVITY_MAX_NUM_POINTERS_IN_MOTION_EVENT \
+ GAMEACTIVITY_MAX_NUM_POINTERS_IN_MOTION_EVENT_OVERRIDE
+#else
+#define GAMEACTIVITY_MAX_NUM_POINTERS_IN_MOTION_EVENT 8
+#endif
+
+/**
+ * \brief Describe a motion event that happened on the GameActivity SurfaceView.
+ *
+ * This is 1:1 mapping to the information contained in a Java `MotionEvent`
+ * (see https://developer.android.com/reference/android/view/MotionEvent).
+ */
+typedef struct GameActivityMotionEvent {
+ int32_t deviceId;
+ int32_t source;
+ int32_t action;
+
+ int64_t eventTime;
+ int64_t downTime;
+
+ int32_t flags;
+ int32_t metaState;
+
+ int32_t actionButton;
+ int32_t buttonState;
+ int32_t classification;
+ int32_t edgeFlags;
+
+ uint32_t pointerCount;
+ GameActivityPointerAxes
+ pointers[GAMEACTIVITY_MAX_NUM_POINTERS_IN_MOTION_EVENT];
+
+ int historySize;
+ long* historicalEventTimesMillis;
+ long* historicalEventTimesNanos;
+ float* historicalAxisValues;
+
+ float precisionX;
+ float precisionY;
+} GameActivityMotionEvent;
+
+float GameActivityMotionEvent_getHistoricalAxisValue(
+ const GameActivityMotionEvent* event, int axis, int pointerIndex,
+ int historyPos);
+
+inline int GameActivityMotionEvent_getHistorySize(
+ const GameActivityMotionEvent* event) {
+ return event->historySize;
+}
+
+inline float GameActivityMotionEvent_getHistoricalX(
+ const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
+ return GameActivityMotionEvent_getHistoricalAxisValue(
+ event, AMOTION_EVENT_AXIS_X, pointerIndex, historyPos);
+}
+
+inline float GameActivityMotionEvent_getHistoricalY(
+ const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
+ return GameActivityMotionEvent_getHistoricalAxisValue(
+ event, AMOTION_EVENT_AXIS_Y, pointerIndex, historyPos);
+}
+
+inline float GameActivityMotionEvent_getHistoricalPressure(
+ const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
+ return GameActivityMotionEvent_getHistoricalAxisValue(
+ event, AMOTION_EVENT_AXIS_PRESSURE, pointerIndex, historyPos);
+}
+
+inline float GameActivityMotionEvent_getHistoricalSize(
+ const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
+ return GameActivityMotionEvent_getHistoricalAxisValue(
+ event, AMOTION_EVENT_AXIS_SIZE, pointerIndex, historyPos);
+}
+
+inline float GameActivityMotionEvent_getHistoricalTouchMajor(
+ const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
+ return GameActivityMotionEvent_getHistoricalAxisValue(
+ event, AMOTION_EVENT_AXIS_TOUCH_MAJOR, pointerIndex, historyPos);
+}
+
+inline float GameActivityMotionEvent_getHistoricalTouchMinor(
+ const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
+ return GameActivityMotionEvent_getHistoricalAxisValue(
+ event, AMOTION_EVENT_AXIS_TOUCH_MINOR, pointerIndex, historyPos);
+}
+
+inline float GameActivityMotionEvent_getHistoricalToolMajor(
+ const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
+ return GameActivityMotionEvent_getHistoricalAxisValue(
+ event, AMOTION_EVENT_AXIS_TOOL_MAJOR, pointerIndex, historyPos);
+}
+
+inline float GameActivityMotionEvent_getHistoricalToolMinor(
+ const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
+ return GameActivityMotionEvent_getHistoricalAxisValue(
+ event, AMOTION_EVENT_AXIS_TOOL_MINOR, pointerIndex, historyPos);
+}
+
+inline float GameActivityMotionEvent_getHistoricalOrientation(
+ const GameActivityMotionEvent* event, int pointerIndex, int historyPos) {
+ return GameActivityMotionEvent_getHistoricalAxisValue(
+ event, AMOTION_EVENT_AXIS_ORIENTATION, pointerIndex, historyPos);
+}
+
+/** \brief Handle the freeing of the GameActivityMotionEvent struct. */
+void GameActivityMotionEvent_destroy(GameActivityMotionEvent* c_event);
+
+/**
+ * \brief Convert a Java `MotionEvent` to a `GameActivityMotionEvent`.
+ *
+ * This is done automatically by the GameActivity: see `onTouchEvent` to set
+ * a callback to consume the received events.
+ * This function can be used if you re-implement events handling in your own
+ * activity.
+ * Ownership of out_event is maintained by the caller.
+ */
+void GameActivityMotionEvent_fromJava(JNIEnv* env, jobject motionEvent,
+ GameActivityMotionEvent* out_event);
+
+/**
+ * \brief Describe a key event that happened on the GameActivity SurfaceView.
+ *
+ * This is 1:1 mapping to the information contained in a Java `KeyEvent`
+ * (see https://developer.android.com/reference/android/view/KeyEvent).
+ * The only exception is the event times, which are reported as
+ * nanoseconds in this struct.
+ */
+typedef struct GameActivityKeyEvent {
+ int32_t deviceId;
+ int32_t source;
+ int32_t action;
+
+ int64_t eventTime;
+ int64_t downTime;
+
+ int32_t flags;
+ int32_t metaState;
+
+ int32_t modifiers;
+ int32_t repeatCount;
+ int32_t keyCode;
+ int32_t scanCode;
+ int32_t unicodeChar;
+} GameActivityKeyEvent;
+
+/**
+ * \brief Convert a Java `KeyEvent` to a `GameActivityKeyEvent`.
+ *
+ * This is done automatically by the GameActivity: see `onKeyUp` and `onKeyDown`
+ * to set a callback to consume the received events.
+ * This function can be used if you re-implement events handling in your own
+ * activity.
+ * Ownership of out_event is maintained by the caller.
+ */
+void GameActivityKeyEvent_fromJava(JNIEnv* env, jobject motionEvent,
+ GameActivityKeyEvent* out_event);
+
+#ifdef __cplusplus
+}
+#endif
+
+/** @} */
+
+#endif // ANDROID_GAME_SDK_GAME_ACTIVITY_EVENTS_H
diff --git a/game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivityLog.h b/game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivityLog.h
new file mode 100644
index 0000000..ba9a9e9
--- /dev/null
+++ b/game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivityLog.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2022 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.
+ */
+#ifndef ANDROID_GAME_SDK_GAME_ACTIVITY_LOG_H_
+#define ANDROID_GAME_SDK_GAME_ACTIVITY_LOG_H_
+
+#define LOG_TAG "GameActivity"
+#include <android/log.h>
+
+#define ALOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__);
+#define ALOGW(...) __android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__);
+#define ALOGD(...) __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__);
+#ifdef NDEBUG
+#define ALOGV(...)
+#else
+#define ALOGV(...) \
+ __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__);
+#endif
+
+/* Returns 2nd arg. Used to substitute default value if caller's vararg list
+ * is empty.
+ */
+#define __android_second(first, second, ...) second
+
+/* If passed multiple args, returns ',' followed by all but 1st arg, otherwise
+ * returns nothing.
+ */
+#define __android_rest(first, ...) , ##__VA_ARGS__
+
+#define android_printAssert(cond, tag, fmt...) \
+ __android_log_assert(cond, tag, \
+ __android_second(0, ##fmt, NULL) __android_rest(fmt))
+
+#define CONDITION(cond) (__builtin_expect((cond) != 0, 0))
+
+#ifndef LOG_ALWAYS_FATAL_IF
+#define LOG_ALWAYS_FATAL_IF(cond, ...) \
+ ((CONDITION(cond)) \
+ ? ((void)android_printAssert(#cond, LOG_TAG, ##__VA_ARGS__)) \
+ : (void)0)
+#endif
+
+#ifndef LOG_ALWAYS_FATAL
+#define LOG_ALWAYS_FATAL(...) \
+ (((void)android_printAssert(NULL, LOG_TAG, ##__VA_ARGS__)))
+#endif
+
+/*
+ * Simplified macro to send a warning system log message using current LOG_TAG.
+ */
+#ifndef SLOGW
+#define SLOGW(...) \
+ ((void)__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__))
+#endif
+
+#ifndef SLOGW_IF
+#define SLOGW_IF(cond, ...) \
+ ((__predict_false(cond)) \
+ ? ((void)__android_log_print(ANDROID_LOG_WARN, LOG_TAG, __VA_ARGS__)) \
+ : (void)0)
+#endif
+
+/*
+ * Versions of LOG_ALWAYS_FATAL_IF and LOG_ALWAYS_FATAL that
+ * are stripped out of release builds.
+ */
+#if LOG_NDEBUG
+
+#ifndef LOG_FATAL_IF
+#define LOG_FATAL_IF(cond, ...) ((void)0)
+#endif
+#ifndef LOG_FATAL
+#define LOG_FATAL(...) ((void)0)
+#endif
+
+#else
+
+#ifndef LOG_FATAL_IF
+#define LOG_FATAL_IF(cond, ...) LOG_ALWAYS_FATAL_IF(cond, ##__VA_ARGS__)
+#endif
+#ifndef LOG_FATAL
+#define LOG_FATAL(...) LOG_ALWAYS_FATAL(__VA_ARGS__)
+#endif
+
+#endif
+
+/*
+ * Assertion that generates a log message when the assertion fails.
+ * Stripped out of release builds. Uses the current LOG_TAG.
+ */
+#ifndef ALOG_ASSERT
+#define ALOG_ASSERT(cond, ...) LOG_FATAL_IF(!(cond), ##__VA_ARGS__)
+#endif
+
+#define LOG_TRACE(...)
+
+#endif // ANDROID_GAME_SDK_GAME_ACTIVITY_LOG_H_
diff --git a/game-activity/prefab-src/modules/game-activity/include/game-activity/native_app_glue/android_native_app_glue.c b/game-activity/prefab-src/modules/game-activity/include/game-activity/native_app_glue/android_native_app_glue.c
index f4fff5f..ebc265e 100644
--- a/game-activity/prefab-src/modules/game-activity/include/game-activity/native_app_glue/android_native_app_glue.c
+++ b/game-activity/prefab-src/modules/game-activity/include/game-activity/native_app_glue/android_native_app_glue.c
@@ -593,6 +593,20 @@
android_app_write_cmd(ToApp(activity), APP_CMD_WINDOW_INSETS_CHANGED);
}
+static void onContentRectChanged(GameActivity* activity, const ARect *rect) {
+ LOGV("ContentRectChanged: %p -- (%d %d) (%d %d)", activity, rect->left, rect->top,
+ rect->right, rect->bottom);
+
+ struct android_app* android_app = ToApp(activity);
+
+ pthread_mutex_lock(&android_app->mutex);
+ android_app->contentRect = *rect;
+
+ android_app_write_cmd(android_app, APP_CMD_CONTENT_RECT_CHANGED);
+ pthread_mutex_unlock(&android_app->mutex);
+}
+
+
JNIEXPORT
void GameActivity_onCreate(GameActivity* activity, void* savedState,
size_t savedStateSize) {
@@ -616,6 +630,7 @@
onNativeWindowRedrawNeeded;
activity->callbacks->onNativeWindowResized = onNativeWindowResized;
activity->callbacks->onWindowInsetsChanged = onWindowInsetsChanged;
+ activity->callbacks->onContentRectChanged = onContentRectChanged;
LOGV("Callbacks set: %p", activity->callbacks);
activity->instance =
diff --git a/game-activity/src/main/java/com/google/androidgamesdk/GameActivity.java b/game-activity/src/main/java/com/google/androidgamesdk/GameActivity.java
index fa43611..00c2890 100644
--- a/game-activity/src/main/java/com/google/androidgamesdk/GameActivity.java
+++ b/game-activity/src/main/java/com/google/androidgamesdk/GameActivity.java
@@ -24,6 +24,7 @@
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.content.res.Configuration;
+import android.content.Context;
import android.graphics.PixelFormat;
import android.os.Build;
import android.os.Bundle;
@@ -58,7 +59,8 @@
public class GameActivity
extends AppCompatActivity
- implements SurfaceHolder.Callback2, Listener, OnApplyWindowInsetsListener {
+ implements SurfaceHolder.Callback2, Listener, OnApplyWindowInsetsListener,
+ OnGlobalLayoutListener {
private static final String LOG_TAG = "GameActivity";
private static final String DEFAULT_NATIVE_LIB_NAME = "main";
@@ -110,6 +112,27 @@
onTextInputEventNative(mNativeHandle, newState);
}
+ @Override
+ public void onGlobalLayout() {
+ mSurfaceView.getLocationInWindow(mLocation);
+ int w = mSurfaceView.getWidth();
+ int h = mSurfaceView.getHeight();
+
+ if (mLocation[0] != mLastContentX || mLocation[1] != mLastContentY
+ || w != mLastContentWidth || h != mLastContentHeight)
+ {
+ mLastContentX = mLocation[0];
+ mLastContentY = mLocation[1];
+ mLastContentWidth = w;
+ mLastContentHeight = h;
+
+ if (!mDestroyed) {
+ onContentRectChangedNative(mNativeHandle, mLastContentX, mLastContentY,
+ mLastContentWidth, mLastContentHeight);
+ }
+ }
+ }
+
// Called when we want to set the input state, e.g. before first showing the IME
public void setTextInputState(State s) {
if (mSurfaceView == null) return;
@@ -125,11 +148,16 @@
private SurfaceHolder mCurSurfaceHolder;
protected final int[] mLocation = new int[2];
+ protected int mLastContentX;
+ protected int mLastContentY;
+ protected int mLastContentWidth;
+ protected int mLastContentHeight;
+
protected boolean mDestroyed;
protected native long initializeNativeCode(String internalDataPath, String obbPath,
- String externalDataPath, AssetManager assetMgr, byte[] savedState);
+ String externalDataPath, AssetManager assetMgr, byte[] savedState, Configuration config);
protected native String getDlError();
@@ -145,7 +173,7 @@
protected native void onStopNative(long handle);
- protected native void onConfigurationChangedNative(long handle);
+ protected native void onConfigurationChangedNative(long handle, Configuration newConfig);
protected native void onTrimMemoryNative(long handle, int level);
@@ -172,6 +200,8 @@
protected native void onWindowInsetsChangedNative(long handle);
+ protected native void onContentRectChangedNative(long handle, int x, int y, int w, int h);
+
/**
* Get the pointer to the C `GameActivity` struct associated to this activity.
* @return the pointer to the C `GameActivity` struct associated to this activity.
@@ -226,6 +256,11 @@
@Override
protected void onCreate(Bundle savedInstanceState) {
onCreateSurfaceView();
+
+ if (mSurfaceView != null) {
+ mSurfaceView.getViewTreeObserver().addOnGlobalLayoutListener(this);
+ }
+
onSetUpWindow();
String libname = new String(DEFAULT_NATIVE_LIB_NAME);
@@ -269,8 +304,8 @@
savedInstanceState != null ? savedInstanceState.getByteArray(KEY_NATIVE_SAVED_STATE) : null;
mNativeHandle = initializeNativeCode(getAbsolutePath(getFilesDir()),
- getAbsolutePath(getObbDir()), getAbsolutePath(getExternalFilesDir(null)),
- getAssets(), nativeSavedState);
+ getAbsolutePath(getObbDir()), getAbsolutePath(getExternalFilesDir(null)), getAssets(),
+ nativeSavedState, getResources().getConfiguration());
if (mNativeHandle == 0) {
throw new UnsatisfiedLinkError(
@@ -338,7 +373,7 @@
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (!mDestroyed) {
- onConfigurationChangedNative(mNativeHandle);
+ onConfigurationChangedNative(mNativeHandle, newConfig);
}
}
diff --git a/game-text-input/CMakeLists.txt b/game-text-input/CMakeLists.txt
index 2a7b757..a59d2f5 100644
--- a/game-text-input/CMakeLists.txt
+++ b/game-text-input/CMakeLists.txt
@@ -18,6 +18,7 @@
set(CMAKE_CXX_STANDARD 17)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/prefab-src/modules/game-text-input/include/)
+include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include/)
set(GAMETEXTINPUT_SRCS
./prefab-src/modules/game-text-input/include/game-text-input/gametextinput.cpp)
diff --git a/game-text-input/prefab-src/modules/game-text-input/include/common b/game-text-input/prefab-src/modules/game-text-input/include/common
new file mode 120000
index 0000000..9388f34
--- /dev/null
+++ b/game-text-input/prefab-src/modules/game-text-input/include/common
@@ -0,0 +1 @@
+../../../../../include/common/
\ No newline at end of file
diff --git a/game-text-input/prefab-src/modules/game-text-input/include/game-text-input/gametextinput.cpp b/game-text-input/prefab-src/modules/game-text-input/include/game-text-input/gametextinput.cpp
index 6a39943..b8244fb 100644
--- a/game-text-input/prefab-src/modules/game-text-input/include/game-text-input/gametextinput.cpp
+++ b/game-text-input/prefab-src/modules/game-text-input/include/game-text-input/gametextinput.cpp
@@ -48,6 +48,7 @@
void processEvent(jobject textInputEvent);
void showIme(uint32_t flags);
void hideIme(uint32_t flags);
+ void restartInput();
void setEventCallback(GameTextInputEventCallback callback, void *context);
jobject stateToJava(const GameTextInputState &state) const;
void stateFromJava(jobject textInputEvent,
@@ -73,6 +74,7 @@
jobject inputConnection_ = nullptr;
jmethodID inputConnectionSetStateMethod_;
jmethodID setSoftKeyboardActiveMethod_;
+ jmethodID restartInputMethod_;
void (*eventCallback_)(void *context,
const struct GameTextInputState *state) = nullptr;
void *eventCallbackContext_ = nullptr;
@@ -164,6 +166,10 @@
input->hideIme(flags);
}
+void GameTextInput_restartInput(struct GameTextInput *input) {
+ input->restartInput();
+}
+
void GameTextInput_setEventCallback(struct GameTextInput *input,
GameTextInputEventCallback callback,
void *context) {
@@ -199,6 +205,8 @@
"(Lcom/google/androidgamesdk/gametextinput/State;)V");
setSoftKeyboardActiveMethod_ = env_->GetMethodID(
inputConnectionClass_, "setSoftKeyboardActive", "(ZI)V");
+ restartInputMethod_ =
+ env_->GetMethodID(inputConnectionClass_, "restartInput", "()V");
stateClassInfo_.text =
env_->GetFieldID(stateJavaClass_, "text", "Ljava/lang/String;");
@@ -307,6 +315,11 @@
flags);
}
+void GameTextInput::restartInput() {
+ if (inputConnection_ == nullptr) return;
+ env_->CallVoidMethod(inputConnection_, restartInputMethod_, false);
+}
+
jobject GameTextInput::stateToJava(const GameTextInputState &state) const {
static jmethodID constructor = nullptr;
if (constructor == nullptr) {
diff --git a/game-text-input/prefab-src/modules/game-text-input/include/game-text-input/gametextinput.h b/game-text-input/prefab-src/modules/game-text-input/include/game-text-input/gametextinput.h
index a85265e..8c33da5 100644
--- a/game-text-input/prefab-src/modules/game-text-input/include/game-text-input/gametextinput.h
+++ b/game-text-input/prefab-src/modules/game-text-input/include/game-text-input/gametextinput.h
@@ -26,12 +26,21 @@
#include <jni.h>
#include <stdint.h>
+#include "common/gamesdk_common.h"
#include "gamecommon.h"
#ifdef __cplusplus
extern "C" {
#endif
+#define GAMETEXTINPUT_MAJOR_VERSION 2
+#define GAMETEXTINPUT_MINOR_VERSION 0
+#define GAMETEXTINPUT_BUGFIX_VERSION 0
+#define GAMETEXTINPUT_PACKED_VERSION \
+ ANDROID_GAMESDK_PACKED_VERSION(GAMETEXTINPUT_MAJOR_VERSION, \
+ GAMETEXTINPUT_MINOR_VERSION, \
+ GAMETEXTINPUT_BUGFIX_VERSION)
+
/**
* This struct holds a span within a region of text from start (inclusive) to
* end (exclusive). An empty span or cursor position is specified with
@@ -174,6 +183,12 @@
void GameTextInput_hideIme(GameTextInput *input, uint32_t flags);
/**
+ * Restarts the input method. Calls InputMethodManager.restartInput().
+ * @param input A valid GameTextInput library handle.
+ */
+void GameTextInput_restartInput(GameTextInput *input);
+
+/**
* Call a callback with the current GameTextInput state, which may have been
* modified by changes in the IME and calls to GameTextInput_setState. We use a
* callback rather than returning the state in order to simplify ownership of
diff --git a/games-controller/src/main/cpp/paddleboat/include/common b/games-controller/src/main/cpp/paddleboat/include/common
new file mode 120000
index 0000000..a3ff523
--- /dev/null
+++ b/games-controller/src/main/cpp/paddleboat/include/common
@@ -0,0 +1 @@
+../../../../../../include/common/
\ No newline at end of file
diff --git a/games-controller/src/main/cpp/paddleboat/include/paddleboat.h b/games-controller/src/main/cpp/paddleboat/include/paddleboat.h
index b1d5c2c..20a91e2 100644
--- a/games-controller/src/main/cpp/paddleboat/include/paddleboat.h
+++ b/games-controller/src/main/cpp/paddleboat/include/paddleboat.h
@@ -37,10 +37,20 @@
#include <stdbool.h>
#include <stdint.h>
+#include "common/gamesdk_common.h"
+
#ifdef __cplusplus
extern "C" {
#endif
+#define PADDLEBOAT_MAJOR_VERSION 2
+#define PADDLEBOAT_MINOR_VERSION 0
+#define PADDLEBOAT_BUGFIX_VERSION 0
+#define PADDLEBOAT_PACKED_VERSION \
+ ANDROID_GAMESDK_PACKED_VERSION(PADDLEBOAT_MAJOR_VERSION, \
+ PADDLEBOAT_MINOR_VERSION, \
+ PADDLEBOAT_BUGFIX_VERSION)
+
/**
* @brief Maximum number of simultaneously connected controllers.
*/
diff --git a/games-controller/src/main/cpp/paddleboat_c.cpp b/games-controller/src/main/cpp/paddleboat_c.cpp
index d6bc14e..5b4d443 100644
--- a/games-controller/src/main/cpp/paddleboat_c.cpp
+++ b/games-controller/src/main/cpp/paddleboat_c.cpp
@@ -21,15 +21,6 @@
extern "C" {
-// Internal macros to track Paddleboat version, do not use directly.
-#define PADDLEBOAT_MAJOR_VERSION 1
-#define PADDLEBOAT_MINOR_VERSION 2
-#define PADDLEBOAT_BUGFIX_VERSION 0
-
-#define PADDLEBOAT_PACKED_VERSION \
- ((PADDLEBOAT_MAJOR_VERSION << 24) | (PADDLEBOAT_MINOR_VERSION << 16) | \
- (PADDLEBOAT_BUGFIX_VERSION))
-
#define PADDLEBOAT_VERSION_CONCAT_NX(PREFIX, MAJOR, MINOR, BUGFIX) \
PREFIX##_##MAJOR##_##MINOR##_##BUGFIX
#define PADDLEBOAT_VERSION_CONCAT(PREFIX, MAJOR, MINOR, BUGFIX) \
diff --git a/games-memory-advice/core/memory_advice_internal.h b/games-memory-advice/core/memory_advice_internal.h
index fde1a34..12c84c2 100644
--- a/games-memory-advice/core/memory_advice_internal.h
+++ b/games-memory-advice/core/memory_advice_internal.h
@@ -19,15 +19,6 @@
#include "memory_advice/memory_advice.h"
#include "memory_advice/memory_advice_debug.h"
-// Memory advice version symbols for tracking the version.
-#define MEMORY_ADVICE_MAJOR_VERSION 1
-#define MEMORY_ADVICE_MINOR_VERSION 0
-#define MEMORY_ADVICE_BUGFIX_VERSION 0
-#define MEMORY_ADVICE_PACKED_VERSION \
- ANDROID_GAMESDK_PACKED_VERSION(MEMORY_ADVICE_MAJOR_VERSION, \
- MEMORY_ADVICE_MINOR_VERSION, \
- MEMORY_ADVICE_BUGFIX_VERSION)
-
// Internal macros to generate a symbol to track Memory Advice version, do not
// use directly.
#define MEMORY_ADVICE_VERSION_CONCAT_NX(PREFIX, MAJOR, MINOR) \
diff --git a/games-memory-advice/core/predictor.cpp b/games-memory-advice/core/predictor.cpp
index 11cf332..16b2b47 100644
--- a/games-memory-advice/core/predictor.cpp
+++ b/games-memory-advice/core/predictor.cpp
@@ -45,6 +45,10 @@
std::string features_file) {
apk_utils::NativeAsset features_asset(features_file.c_str());
+ if (!features_asset.IsValid()) {
+ return MEMORYADVICE_ERROR_TFLITE_MODEL_INVALID;
+ }
+
// Get the features list from the corresponding asset,
// which is a list of strings denoted with quotation marks
std::string features_string(
@@ -71,6 +75,10 @@
// Read the tflite model from the given asset file
model_asset = std::make_unique<apk_utils::NativeAsset>(model_file.c_str());
+
+ if (!model_asset->IsValid()) {
+ return MEMORYADVICE_ERROR_TFLITE_MODEL_INVALID;
+ }
const char* model_buffer =
static_cast<const char*>(AAsset_getBuffer(*model_asset));
const size_t model_capacity =
diff --git a/games-performance-tuner/core/request_info.cpp b/games-performance-tuner/core/request_info.cpp
index b9968ea..ba45462 100644
--- a/games-performance-tuner/core/request_info.cpp
+++ b/games-performance-tuner/core/request_info.cpp
@@ -127,6 +127,14 @@
info.soc_manufacturer =
gamesdk::jni::android::os::Build::SOC_MANUFACTURER().C();
}
+
+ gamesdk::jni::android::util::DisplayMetrics display_metrics;
+ gamesdk::jni::AppContext()
+ .getWindowManager()
+ .getDefaultDisplay()
+ .getMetrics(display_metrics);
+ info.height_pixels = display_metrics.heightPixels();
+ info.width_pixels = display_metrics.widthPixels();
}
info.tuningfork_version = TUNINGFORK_PACKED_VERSION;
info.swappy_version = settings.c_settings.swappy_version;
diff --git a/games-performance-tuner/core/request_info.h b/games-performance-tuner/core/request_info.h
index 17db1c0..7bc8d63 100644
--- a/games-performance-tuner/core/request_info.h
+++ b/games-performance-tuner/core/request_info.h
@@ -51,6 +51,8 @@
std::string soc_manufacturer;
int64_t swap_total_bytes;
uint32_t swappy_version;
+ int32_t height_pixels;
+ int32_t width_pixels;
// Note that this will include an empty experiment_id and
// current_fidelity_parameters.
diff --git a/games-performance-tuner/core/tuningfork_utils.cpp b/games-performance-tuner/core/tuningfork_utils.cpp
index a86373b..0cd04bc 100644
--- a/games-performance-tuner/core/tuningfork_utils.cpp
+++ b/games-performance-tuner/core/tuningfork_utils.cpp
@@ -249,7 +249,9 @@
{"soc_model", request_info.soc_model},
{"soc_manufacturer", request_info.soc_manufacturer},
{"swap_total_bytes",
- static_cast<double>(request_info.swap_total_bytes)}};
+ static_cast<double>(request_info.swap_total_bytes)},
+ {"height_pixels", request_info.height_pixels},
+ {"width_pixels", request_info.width_pixels}};
}
} // namespace json_utils
diff --git a/hooks/check_bugfix_version.sh b/hooks/check_bugfix_version.sh
deleted file mode 100755
index aba002f..0000000
--- a/hooks/check_bugfix_version.sh
+++ /dev/null
@@ -1,28 +0,0 @@
-#!/bin/bash
-
-SWAPPY_PATTERN="games-frame-pacing/.*[.](cpp|h)$"
-TUNINGFORK_PATTERN="src/tuningfork/.*[.](cpp|h)$"
-
-SWAPPY_COMMON_H="include/swappy/swappy_common.h"
-TUNINGFORK_H="include/tuningfork/tuningfork.h"
-
-files=$2
-swappyChanged=0
-tuningforkChanged=0
-for file in ${files[@]}; do
- echo $file
-
- if [[ $file =~ $SWAPPY_PATTERN ]]; then
- swappyChanged=1
- fi
- if [[ $file =~ $TUNINGFORK_PATTERN ]]; then
- tuningforkChanged=1
- fi
-done
-
-echo "Swappy changed: $swappyChanged"
-echo "TuningFork changed: $tuningforkChanged"
-
-# TODO (willosborn): check that swappy and tuningfork versions match those in VERSIONS
-
-exit 0
diff --git a/hooks/check_library_versions.sh b/hooks/check_library_versions.sh
new file mode 100755
index 0000000..ce2b95f
--- /dev/null
+++ b/hooks/check_library_versions.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+
+SWAPPY_COMMON_H="include/swappy/swappy_common.h"
+TUNINGFORK_H="include/tuningfork/tuningfork.h"
+
+VERSIONS="VERSIONS"
+
+library_names=(games-frame-pacing games-performance-tuner game-activity game-text-input games-controller games-memory-advice)
+header_files=(include/swappy/swappy_common.h include/tuningfork/tuningfork.h game-activity/prefab-src/modules/game-activity/include/game-activity/GameActivity.h game-text-input/prefab-src/modules/game-text-input/include/game-text-input/gametextinput.h include/paddleboat/paddleboat.h include/memory_advice/memory_advice.h)
+library_version_prefix=(SWAPPY TUNINGFORK GAMEACTIVITY GAMETEXTINPUT PADDLEBOAT MEMORY_ADVICE)
+
+
+for i in "${!library_names[@]}"; do
+ library="${library_names[i]}"
+ header="${header_files[i]}"
+ prefix="${library_version_prefix[i]}"
+ [[ `cat VERSIONS` =~ $library[[:space:]]*([0-9]+.[0-9]+.[0-9]+)[[:space:]]*([a-z]*) ]]
+ versions_version="${BASH_REMATCH[1]}"
+ version_suffix="${BASH_REMATCH[2]}"
+ [[ `cat $header` =~ ${prefix}_MAJOR_VERSION.([0-9]+) ]]
+ major="${BASH_REMATCH[1]}"
+ [[ `cat $header` =~ ${prefix}_MINOR_VERSION.([0-9]+) ]]
+ minor="${BASH_REMATCH[1]}"
+ [[ `cat $header` =~ ${prefix}_BUGFIX_VERSION.([0-9]+) ]]
+ bugfix="${BASH_REMATCH[1]}"
+ header_version="${major}.${minor}.${bugfix}"
+ if [[ "${major}.${minor}.${bugfix}" != $versions_version ]]; then
+ echo "Version mismatch! For ${library}, the version declared in its header is ${header_version} but the version declared in the VERSIONS file is ${versions_version}."
+ exit 1
+ fi
+ if [[ $version_suffix =~ "alpha" ]] && [[ $bugfix != "0" ]]; then
+ echo "Invalid version! ${library} is declared as an alpha release, but has a bugfix version."
+ exit 1
+ fi
+ if [[ $version_suffix =~ "beta" ]] && [[ $bugfix != "0" ]]; then
+ echo "Invalid version! ${library} is declared as a beta release, but has a bugfix version."
+ exit 1
+ fi
+done
+
+exit 0
diff --git a/hooks/check_swappy_abi_version.sh b/hooks/check_swappy_abi_version.sh
deleted file mode 100755
index 7c2957d..0000000
--- a/hooks/check_swappy_abi_version.sh
+++ /dev/null
@@ -1,32 +0,0 @@
-#!/bin/bash
-
-SWAPPY_GL_H="include/swappy/swappyGL.h"
-SWAPPY_GL_EXTRA_H="include/swappy/swappyGL_extra.h"
-SWAPPY_VK_H="include/swappy/swappyVk.h"
-SWAPPY_VK_EXTRA_H="include/swappy/swappyVk_extra.h"
-SWAPPY_COMMON_H="include/swappy/swappy_common.h"
-
-SWAPPY_HEADERS=($SWAPPY_GL_H $SWAPPY_GL_EXTRA_H $SWAPPY_VK_H $SWAPPY_VK_EXTRA_H $SWAPPY_COMMON_H)
-
-files=$2
-headerChanged=0
-for file in ${files[@]}; do
- for header in ${SWAPPY_HEADERS[@]}; do
- if [[ $file =~ $header ]]; then
- headerChanged=1
- break
- fi
- done
-done
-
-if [ $headerChanged -eq "1" ]; then
- majorVersion=`git show $1 $SWAPPY_COMMON_H | grep "#define SWAPPY_MAJOR_VERSION" | wc -l`
- minorVersion=`git show $1 $SWAPPY_COMMON_H | grep "#define SWAPPY_MINOR_VERSION" | wc -l`
- # echo "version_files $version_files"
- if [[ $majorVersion -eq "0" && $minorVersion -eq "0" ]]; then
- echo "Warning: did you break the Swappy ABI without changing SWAPPY_MAJOR_VERSION or SWAPPY_MINOR_VERSION ?"
- fi
-
-fi
-
-exit 0
diff --git a/hooks/check_tuningfork_abi_version.sh b/hooks/check_tuningfork_abi_version.sh
deleted file mode 100755
index fdf30cb..0000000
--- a/hooks/check_tuningfork_abi_version.sh
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/bin/bash
-
-TUNINGFORK_H="include/tuningfork/tuningfork.h"
-TUNINGFORK_EXTRA_H="include/tuningfork/tuningfork_extra.h"
-UNITY_TUNINGFORK_H="include/tuningfork/unity_tuningfork.h"
-TUNINGFORK_HEADERS=($TUNINGFORK_H $TUNINGFORK_EXTRA_H $UNITY_TUNINGFORK_H)
-
-files=$2
-headerChanged=0
-for file in ${files[@]}; do
- for header in ${TUNINGFORK_HEADERS[@]}; do
- if [[ $file =~ $header ]]; then
- headerChanged=1
- break
- fi
- done
-done
-
-if [ $headerChanged -eq "1" ]; then
-
- majorVersion=`git show $1 $TUNINGFORK_H | grep "#define TUNINGFORK_MAJOR_VERSION" | wc -l`
- minorVersion=`git show $1 $TUNINGFORK_H | grep "#define TUNINGFORK_MINOR_VERSION" | wc -l`
- # echo "version_files $version_files"
- if [[ $majorVersion -eq "0" && $minorVersion -eq "0" ]]; then
- echo "Warning: did you break the TuningFork ABI without changing TUNINGFORK_MAJOR_VERSION or TUNINGFORK_MINOR_VERSION ?"
- fi
-
-fi
-
-exit 0
diff --git a/include/common/gamesdk_common.h b/include/common/gamesdk_common.h
index 8512262..d29ac01 100644
--- a/include/common/gamesdk_common.h
+++ b/include/common/gamesdk_common.h
@@ -31,11 +31,11 @@
// There are separate versions for each GameSDK component that use this format:
#define ANDROID_GAMESDK_PACKED_VERSION(MAJOR, MINOR, BUGFIX) \
- ((MAJOR << 16) | (MINOR) | (BUGFIX << 8))
+ ((MAJOR << 16) | (MINOR << 8) | (BUGFIX))
// Accessors
#define ANDROID_GAMESDK_MAJOR_VERSION(PACKED) ((PACKED) >> 16)
-#define ANDROID_GAMESDK_MINOR_VERSION(PACKED) ((PACKED)&0xff)
-#define ANDROID_GAMESDK_BUGFIX_VERSION(PACKED) (((PACKED) >> 8) & 0xff)
+#define ANDROID_GAMESDK_MINOR_VERSION(PACKED) (((PACKED) >> 8) & 0xff)
+#define ANDROID_GAMESDK_BUGFIX_VERSION(PACKED) ((PACKED) & 0xff)
#define AGDK_STRING_VERSION(MAJOR, MINOR, BUGFIX, GIT) \
#MAJOR "." #MINOR "." #BUGFIX "." #GIT
diff --git a/include/memory_advice/memory_advice.h b/include/memory_advice/memory_advice.h
index 7d714e9..340744e 100644
--- a/include/memory_advice/memory_advice.h
+++ b/include/memory_advice/memory_advice.h
@@ -25,10 +25,20 @@
#include <jni.h>
#include <stdint.h>
+#include "common/gamesdk_common.h"
+
#ifdef __cplusplus
extern "C" {
#endif
+#define MEMORY_ADVICE_MAJOR_VERSION 2
+#define MEMORY_ADVICE_MINOR_VERSION 0
+#define MEMORY_ADVICE_BUGFIX_VERSION 0
+#define MEMORY_ADVICE_PACKED_VERSION \
+ ANDROID_GAMESDK_PACKED_VERSION(TUNINGFORK_MAJOR_VERSION, \
+ TUNINGFORK_MINOR_VERSION, \
+ TUNINGFORK_BUGFIX_VERSION)
+
/**
* @brief All the error codes that can be returned by MemoryAdvice functions.
*/
diff --git a/include/swappy/swappyVk.h b/include/swappy/swappyVk.h
index 4bd7d0d..847bc75 100644
--- a/include/swappy/swappyVk.h
+++ b/include/swappy/swappyVk.h
@@ -25,7 +25,9 @@
#include "jni.h"
#include "swappy_common.h"
+#ifndef VK_NO_PROTOTYPES
#define VK_NO_PROTOTYPES 1
+#endif
#include <vulkan/vulkan.h>
#ifdef __cplusplus
@@ -261,6 +263,14 @@
void SwappyVk_injectTracer(const SwappyTracer* tracer);
/**
+ * @brief Remove callbacks that were previously added using
+ * SwappyVk_injectTracer.
+ *
+ * @param[in] tracer - Collection of callback functions
+ */
+void SwappyVk_uninjectTracer(const SwappyTracer* tracer);
+
+/**
* @brief A structure enabling you to provide your own Vulkan function wrappers
* by calling ::SwappyVk_setFunctionProvider.
*
diff --git a/include/swappy/swappy_common.h b/include/swappy/swappy_common.h
index 6797521..ed2386f 100644
--- a/include/swappy/swappy_common.h
+++ b/include/swappy/swappy_common.h
@@ -47,8 +47,8 @@
#define SWAPPY_SYSTEM_PROP_KEY_DISABLE "swappy.disable"
// Internal macros to track Swappy version, do not use directly.
-#define SWAPPY_MAJOR_VERSION 1
-#define SWAPPY_MINOR_VERSION 10
+#define SWAPPY_MAJOR_VERSION 2
+#define SWAPPY_MINOR_VERSION 0
#define SWAPPY_BUGFIX_VERSION 0
#define SWAPPY_PACKED_VERSION \
ANDROID_GAMESDK_PACKED_VERSION(SWAPPY_MAJOR_VERSION, SWAPPY_MINOR_VERSION, \
diff --git a/include/tuningfork/tuningfork.h b/include/tuningfork/tuningfork.h
index 237e058..1395c41 100644
--- a/include/tuningfork/tuningfork.h
+++ b/include/tuningfork/tuningfork.h
@@ -47,8 +47,8 @@
/** @cond INTERNAL */
-#define TUNINGFORK_MAJOR_VERSION 1
-#define TUNINGFORK_MINOR_VERSION 5
+#define TUNINGFORK_MAJOR_VERSION 2
+#define TUNINGFORK_MINOR_VERSION 0
#define TUNINGFORK_BUGFIX_VERSION 0
#define TUNINGFORK_PACKED_VERSION \
ANDROID_GAMESDK_PACKED_VERSION(TUNINGFORK_MAJOR_VERSION, \
diff --git a/prepproto.gradle b/prepproto.gradle
index f4eb6ac..07f881b 100644
--- a/prepproto.gradle
+++ b/prepproto.gradle
@@ -54,11 +54,28 @@
setEnvironment env
commandLine "python", "setup.py", "install", "--user"
}
- // Generate nano-pb requirements
- exec {
- workingDir "${gameSdkRoot}/../external/nanopb-c/generator/proto"
- setEnvironment env
- commandLine 'make'
+ // Generate nano-pb requirements.
+ // Nanopb provides a Makefile to generate the requirements, however on windows it
+ // is not trivial to work with make. Instead we just use protoc to generate the requirements
+ // which is what the Makefile does as well to begin with.
+ if (OperatingSystem.current().isWindows()) {
+ exec {
+ workingDir "${gameSdkRoot}/../external/nanopb-c/generator/proto"
+ setEnvironment env
+ commandLine "${protocBinDir}/protoc.exe", "nanopb.proto", "--python_out=."
+ }
+ exec {
+ workingDir "${gameSdkRoot}/../external/nanopb-c/generator/proto"
+ setEnvironment env
+ commandLine "${protocBinDir}/protoc.exe", "plugin.proto", "--python_out=."
+ }
+ }
+ else {
+ exec {
+ workingDir "${gameSdkRoot}/../external/nanopb-c/generator/proto"
+ setEnvironment env
+ commandLine "make"
+ }
}
outputs.upToDateWhen { false }
}
diff --git a/samples/agdktunnel/app/build.gradle b/samples/agdktunnel/app/build.gradle
index f7bbed5..48a7015 100644
--- a/samples/agdktunnel/app/build.gradle
+++ b/samples/agdktunnel/app/build.gradle
@@ -146,7 +146,7 @@
// Android Performance Tuner validation setup and protoc compile tasks
task createJar(type: GradleBuild) {
- buildFile = GameSDKPath + '/src/tuningfork/tools/validation/build.gradle'
+ buildFile = GameSDKPath + '/games-performance-tuner/tools/validation/build.gradle'
tasks = ['createJar']
}
@@ -161,7 +161,7 @@
task buildTuningForkBinFiles(type: JavaExec) {
dependsOn createJar
main "-jar"
- args (GameSDKPath + "/src/tuningfork/tools/validation/build/libs/TuningforkApkValidationTool.jar",
+ args (GameSDKPath + "/games-performance-tuner/tools/validation/build/libs/TuningforkApkValidationTool.jar",
"--tuningforkPath",
"src/main/assets/tuningfork",
"--protoCompiler",
diff --git a/samples/game_text_input/game_text_input_testbed/app/src/main/cpp/game-input.cpp b/samples/game_text_input/game_text_input_testbed/app/src/main/cpp/game-input.cpp
index a569e79..7fc1014 100644
--- a/samples/game_text_input/game_text_input_testbed/app/src/main/cpp/game-input.cpp
+++ b/samples/game_text_input/game_text_input_testbed/app/src/main/cpp/game-input.cpp
@@ -82,6 +82,11 @@
}
extern "C" JNIEXPORT void JNICALL
+Java_com_gametextinput_testbed_MainActivity_restartInput(JNIEnv *env, jobject thiz) {
+ GameTextInput_restartInput(gameTextInput);
+}
+
+extern "C" JNIEXPORT void JNICALL
Java_com_gametextinput_testbed_MainActivity_sendSelectionToStart(JNIEnv *env,
jobject thiz) {
GameTextInput_getState(gameTextInput, [](void* context, const GameTextInputState* state) {
diff --git a/samples/game_text_input/game_text_input_testbed/app/src/main/java/com/gameinput/testbed/MainActivity.java b/samples/game_text_input/game_text_input_testbed/app/src/main/java/com/gameinput/testbed/MainActivity.java
index a50a8a5..86015ab 100644
--- a/samples/game_text_input/game_text_input_testbed/app/src/main/java/com/gameinput/testbed/MainActivity.java
+++ b/samples/game_text_input/game_text_input_testbed/app/src/main/java/com/gameinput/testbed/MainActivity.java
@@ -37,6 +37,7 @@
native void setInputConnectionNative(InputConnection c);
native void showIme();
native void hideIme();
+ native void restartInput();
native void sendSelectionToStart();
native void sendSelectionToEnd();
@@ -66,21 +67,21 @@
EditorInfo editorInfo = new EditorInfo();
editorInfo.inputType = InputType.TYPE_NULL;
inputEnabledTextView.mInputConnection.setEditorInfo(editorInfo);
- inputEnabledTextView.mInputConnection.restartInput();
+ restartInput();
});
Button typeTextButton = (Button) findViewById(R.id.type_text_button);
typeTextButton.setOnClickListener(view -> {
EditorInfo editorInfo = new EditorInfo();
editorInfo.inputType = InputType.TYPE_CLASS_TEXT;
inputEnabledTextView.mInputConnection.setEditorInfo(editorInfo);
- inputEnabledTextView.mInputConnection.restartInput();
+ restartInput();
});
Button typeNumberButton = (Button) findViewById(R.id.type_number_button);
typeNumberButton.setOnClickListener(view -> {
EditorInfo editorInfo = new EditorInfo();
editorInfo.inputType = InputType.TYPE_CLASS_NUMBER;
inputEnabledTextView.mInputConnection.setEditorInfo(editorInfo);
- inputEnabledTextView.mInputConnection.restartInput();
+ restartInput();
});
onCreated();
diff --git a/samples/memory_advice/hogger/app/CMakeLists.txt b/samples/memory_advice/hogger/app/CMakeLists.txt
index 2f602ec..677e23a 100644
--- a/samples/memory_advice/hogger/app/CMakeLists.txt
+++ b/samples/memory_advice/hogger/app/CMakeLists.txt
@@ -8,11 +8,6 @@
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti" )
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DGOOGLE_PROTOBUF_NO_RTTI -DHAVE_PTHREAD")
-set( MEMORYADVICE_RESOURCES_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../../test/memoryadvice/memoryadvice/src/main/resources")
-
-file(GLOB TF_MODEL_FILES "${MEMORYADVICE_RESOURCES_DIR}/*.*")
-file(COPY ${TF_MODEL_FILES} DESTINATION ${CMAKE_CURRENT_SOURCE_DIR}/src/main/assets)
-
include_directories(../../../../include)
include_directories(../../../common/include ) # Samples Includes
diff --git a/samples/memory_advice/hogger/app/build.gradle b/samples/memory_advice/hogger/app/build.gradle
index 8b4fab0..20e4bfb 100644
--- a/samples/memory_advice/hogger/app/build.gradle
+++ b/samples/memory_advice/hogger/app/build.gradle
@@ -41,6 +41,15 @@
}
}
+task copyAssets() {
+ copy {
+ from "../../../../test/memoryadvice/memoryadvice/src/main/resources"
+ into "src/main/assets"
+ }
+}
+
+tasks.preBuild.dependsOn('copyAssets')
+
dependencies {
implementation 'androidx.appcompat:appcompat:1.1.0'
diff --git a/src/common/JNIUtil.h b/src/common/JNIUtil.h
index decfd01..702e24d 100644
--- a/src/common/JNIUtil.h
+++ b/src/common/JNIUtil.h
@@ -231,6 +231,10 @@
env->DeleteLocalRef(imclassloaderClass);
}
#endif // #ifdef ANDROIDGAMESDK_NO_BINARY_DEX_LINKAGE
+ } else {
+ // Register the native methods loaded by the classLoaderClass
+ env->RegisterNatives(targetClass, nativeMethods,
+ nativeMethodsSize);
}
env->DeleteLocalRef(className);
return targetClass;
diff --git a/src/common/jni/jni_wrap.h b/src/common/jni/jni_wrap.h
index 4b08e73..6e84cca 100644
--- a/src/common/jni/jni_wrap.h
+++ b/src/common/jni/jni_wrap.h
@@ -315,6 +315,41 @@
namespace android {
+namespace util {
+
+class DisplayMetrics : public java::Object {
+ public:
+ DisplayMetrics(java::Object&& o) : java::Object(std::move(o)) {}
+ DisplayMetrics()
+ : java::Object("android/util/DisplayMetrics", "()V") {}
+ int heightPixels() const { return obj_.GetIntField("heightPixels"); }
+ int widthPixels() const { return obj_.GetIntField("widthPixels"); }
+};
+
+} // namespace util
+
+namespace view {
+
+class Display : public java::Object {
+ public:
+ Display(java::Object&& o) : java::Object(std::move(o)) {}
+ void getMetrics(util::DisplayMetrics& displayMetrics) {
+ CallOVMethod("getMetrics", "android/util/DisplayMetrics",
+ displayMetrics);
+ }
+};
+
+class WindowManager : public java::Object {
+ public:
+ WindowManager(java::Object&& o) : java::Object(std::move(o)) {}
+ Display getDefaultDisplay() {
+ return CallVOMethod("getDefaultDisplay",
+ "android/view/Display");
+ }
+};
+
+} // namespace view
+
namespace content {
namespace pm {
@@ -443,6 +478,10 @@
return CallVOMethod("getPackageManager",
"android/content/pm/PackageManager");
}
+ android::view::WindowManager getWindowManager() {
+ return CallVOMethod("getWindowManager",
+ "android/view/WindowManager");
+ }
jni::String getPackageName() { return CallVSMethod("getPackageName"); }
res::AssetManager getAssets() {
return CallVOMethod("getAssets", "android/content/res/AssetManager");
diff --git a/test/memoryadvice/README.md b/test/memoryadvice/README.md
index d342944..ec9d08a 100644
--- a/test/memoryadvice/README.md
+++ b/test/memoryadvice/README.md
@@ -156,7 +156,7 @@
## Adding the library to an Android project
The library is published on
-[Google's Maven repository](https://maven.google.com/web/index.html?q=com.google.android.games#com.google.android.games:memory-advice:0.24).
+[Google's Maven repository](https://maven.google.com/web/index.html?q=com.google.android.games#com.google.android.games:memory-advice:0.25).
In the application root `build.gradle` file, ensure `google()` is specified as a
repository for the project, as well as `jitpack.io` for some of its
@@ -180,7 +180,7 @@
```gradle
dependencies {
// ..
- implementation 'com.google.android.games:memory-advice:0.24'
+ implementation 'com.google.android.games:memory-advice:0.25'
}
```
diff --git a/test/memoryadvice/memoryadvice/build.gradle b/test/memoryadvice/memoryadvice/build.gradle
index f4d1cab..f072060 100644
--- a/test/memoryadvice/memoryadvice/build.gradle
+++ b/test/memoryadvice/memoryadvice/build.gradle
@@ -10,7 +10,7 @@
minSdkVersion 19
versionCode 9
// LINT.IfChange
- versionName '0.24'
+ versionName '0.25'
// LINT.ThenChange(../README.md)
multiDexEnabled true
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
diff --git a/test/tuningfork/endtoend/abandoned_loading.cpp b/test/tuningfork/endtoend/abandoned_loading.cpp
index d9af8c8..9568c66 100644
--- a/test/tuningfork/endtoend/abandoned_loading.cpp
+++ b/test/tuningfork/endtoend/abandoned_loading.cpp
@@ -37,12 +37,14 @@
"device": "",
"fingerprint": "",
"gles_version": {"major": 0, "minor": 0},
+ "height_pixels": 0,
"model": "",
"product": "",
"soc_manufacturer": "",
"soc_model": "",
"swap_total_bytes": 123,
- "total_memory_bytes": 0
+ "total_memory_bytes": 0,
+ "width_pixels": 0
},
"game_sdk_info": {"session_id": "", "version": "1.0.0"},
"time_period": {"end_time": "1970-01-01T00:00:00.000000Z",
diff --git a/test/tuningfork/endtoend/battery.cpp b/test/tuningfork/endtoend/battery.cpp
index 8d6f68d..a69a7b1 100644
--- a/test/tuningfork/endtoend/battery.cpp
+++ b/test/tuningfork/endtoend/battery.cpp
@@ -62,12 +62,14 @@
"major": 0,
"minor": 0
},
+ "height_pixels": 0,
"model": "",
"product": "",
"soc_manufacturer": "",
"soc_model": "",
"swap_total_bytes": 123,
- "total_memory_bytes": 0
+ "total_memory_bytes": 0,
+ "width_pixels": 0
},
"game_sdk_info": {
"session_id": "",
diff --git a/test/tuningfork/endtoend/common.cpp b/test/tuningfork/endtoend/common.cpp
index 2b45f30..d9925a7 100644
--- a/test/tuningfork/endtoend/common.cpp
+++ b/test/tuningfork/endtoend/common.cpp
@@ -32,12 +32,14 @@
"major": 0,
"minor": 0
},
+ "height_pixels": 0,
"model": "",
"product": "",
"soc_manufacturer": "",
"soc_model": "",
"swap_total_bytes": 123,
- "total_memory_bytes": 0
+ "total_memory_bytes": 0,
+ "width_pixels": 0
},
"game_sdk_info": {
"session_id": "",
@@ -63,12 +65,14 @@
"major": 0,
"minor": 0
},
+ "height_pixels": 0,
"model": "",
"product": "",
"soc_manufacturer": "",
"soc_model": "",
"swap_total_bytes": 123,
- "total_memory_bytes": 0
+ "total_memory_bytes": 0,
+ "width_pixels": 0
},
"game_sdk_info": {
"session_id": "",
diff --git a/test/tuningfork/endtoend/fidelityparam_download.cpp b/test/tuningfork/endtoend/fidelityparam_download.cpp
index ff34f68..a854d8a 100644
--- a/test/tuningfork/endtoend/fidelityparam_download.cpp
+++ b/test/tuningfork/endtoend/fidelityparam_download.cpp
@@ -128,12 +128,14 @@
"major": 0,
"minor": 0
},
+ "height_pixels": 0,
"model": "",
"product": "",
"soc_manufacturer": "",
"soc_model": "",
"swap_total_bytes": 123,
- "total_memory_bytes": 0
+ "total_memory_bytes": 0,
+ "width_pixels": 0
},
"name": "applications//apks/0"
})";
diff --git a/test/tuningfork/endtoend/memory.cpp b/test/tuningfork/endtoend/memory.cpp
index 79c6303..5648f23 100644
--- a/test/tuningfork/endtoend/memory.cpp
+++ b/test/tuningfork/endtoend/memory.cpp
@@ -66,12 +66,14 @@
"major": 0,
"minor": 0
},
+ "height_pixels": 0,
"model": "",
"product": "",
"soc_manufacturer": "",
"soc_model": "",
"swap_total_bytes": 123,
- "total_memory_bytes": 0
+ "total_memory_bytes": 0,
+ "width_pixels": 0
},
"game_sdk_info": {
"session_id": "",
diff --git a/test/tuningfork/endtoend/time_based.cpp b/test/tuningfork/endtoend/time_based.cpp
index f126407..f64e70f 100644
--- a/test/tuningfork/endtoend/time_based.cpp
+++ b/test/tuningfork/endtoend/time_based.cpp
@@ -236,12 +236,14 @@
"major": 0,
"minor": 0
},
+ "height_pixels": 0,
"model": "",
"product": "",
"soc_manufacturer": "",
"soc_model": "",
"swap_total_bytes": 123,
- "total_memory_bytes": 0
+ "total_memory_bytes": 0,
+ "width_pixels": 0
},
"game_sdk_info": {
"session_id": "",
@@ -314,12 +316,14 @@
"major": 0,
"minor": 0
},
+ "height_pixels": 0,
"model": "",
"product": "",
"soc_manufacturer": "",
"soc_model": "",
"swap_total_bytes": 123,
- "total_memory_bytes": 0
+ "total_memory_bytes": 0,
+ "width_pixels": 0
},
"game_sdk_info": {
"session_id": "",
diff --git a/test/tuningfork/serialization_test.cpp b/test/tuningfork/serialization_test.cpp
index cedeb4c..bb2a604 100644
--- a/test/tuningfork/serialization_test.cpp
+++ b/test/tuningfork/serialization_test.cpp
@@ -50,7 +50,9 @@
"SOC_MODEL" /*soc_model*/,
"SOC_MANUFACTURER" /*soc_manufacturer*/,
234 /*swap_total_bytes*/,
- ANDROID_GAMESDK_PACKED_VERSION(2, 7, 0) /*swappy_version*/};
+ ANDROID_GAMESDK_PACKED_VERSION(2, 7, 0) /*swappy_version*/,
+ 1024 /*height_pixels*/,
+ 768 /*width_pixels*/};
std::string test_device_info_ser = R"TF({
"brand": "BRAND",
@@ -61,12 +63,14 @@
"gles_version": {
"major": 5, "minor": 21907
},
+ "height_pixels": 1024,
"model": "MODEL",
"product": "PRODUCT",
"soc_manufacturer": "SOC_MANUFACTURER",
"soc_model": "SOC_MODEL",
"swap_total_bytes": 234,
- "total_memory_bytes": 2387
+ "total_memory_bytes": 2387,
+ "width_pixels": 768
})TF";
void CheckDeviceInfo(const RequestInfo& info) {
@@ -92,12 +96,14 @@
"major": 5,
"minor": 21907
},
+ "height_pixels": 1024,
"model": "MODEL",
"product": "PRODUCT",
"soc_manufacturer": "SOC_MANUFACTURER",
"soc_model": "SOC_MODEL",
"swap_total_bytes": 234,
- "total_memory_bytes": 2387
+ "total_memory_bytes": 2387,
+ "width_pixels": 768
},
"game_sdk_info": {
"session_id": "sess",
diff --git a/third_party/cube/app/src/main/cpp/cube.c b/third_party/cube/app/src/main/cpp/cube.c
index bcf3c9c..a7c629f 100644
--- a/third_party/cube/app/src/main/cpp/cube.c
+++ b/third_party/cube/app/src/main/cpp/cube.c
@@ -1580,6 +1580,9 @@
tracer.startFrame = swappy_trace_test_startFrame;
tracer.swapIntervalChanged = swappy_trace_test_swapIntervalChanged;
SwappyVk_injectTracer(&tracer);
+ // Test uninject tracer function.
+ SwappyVk_uninjectTracer(&tracer);
+ SwappyVk_injectTracer(&tracer);
demo->tracer_injected = true;
}