diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.kt b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.kt index 9f71a56a6..ad8261e0e 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.kt +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/GamesListDelegate.kt @@ -1764,8 +1764,13 @@ class GamesListDelegate(delegator: Delegator) : DlgDelegate.Action.WRITE_LOG_DB) R.id.games_menu_statsShow -> { - val stats = XwJNI.sts_export().toString() - makeOkOnlyBuilder(stats) + val stats = XwJNI.sts_export() + val pairs = ArrayList() + stats.keys().forEach { + val value = stats.getLong(it) + pairs.add("$it: $value") + } + makeOkOnlyBuilder(TextUtils.join("\n", pairs)) .show() } R.id.games_menu_statsClear -> XwJNI.sts_clearAll() diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MQTTUtils.kt b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MQTTUtils.kt index c40eff025..3f275c531 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MQTTUtils.kt +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/MQTTUtils.kt @@ -43,6 +43,7 @@ import org.eehouse.android.xw4.jni.CommsAddrRec import org.eehouse.android.xw4.jni.CommsAddrRec.CommsConnType import org.eehouse.android.xw4.jni.CommsAddrRec.ConnExpl import org.eehouse.android.xw4.jni.XwJNI +import org.eehouse.android.xw4.jni.XwJNI.STAT import org.eehouse.android.xw4.jni.XwJNI.TopicsAndPackets import org.eehouse.android.xw4.loc.LocUtils import org.eehouse.android.xw4.TimerReceiver.TimerCallback @@ -122,7 +123,8 @@ object MQTTUtils { MQTTServiceHelper(context).handleInvitation(nli) } - fun handleMessage(context: Context, from: CommsAddrRec, gameID: Int, msg: ByteArray) + fun handleMessage(context: Context, from: CommsAddrRec, + gameID: Int, msg: ByteArray) { val rowids = DBUtils.getRowIDsFor(context, gameID) Log.d(TAG, "handleMessage(): got %d rows for gameID %X", rowids.size, gameID) @@ -409,7 +411,7 @@ object MQTTUtils { val packet = ByteArray(byteBuf.capacity()) byteBuf.get(packet) add(IncomingTask(topic.toString(), packet)) - + XwJNI.sts_increment(STAT.STAT_MQTT_RCVD) } else { Log.d( TAG, "no message found!!") } @@ -493,6 +495,7 @@ object MQTTUtils { } else { // Handle successful publish, e.g. logging or incrementing a metric TimerReceiver.setBackoff(mContext, sTimerCallbacks, MIN_BACKOFF) + XwJNI.sts_increment(STAT.STAT_MQTT_SENT) } } } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/DUtilCtxt.kt b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/DUtilCtxt.kt index 307bd73be..8c7a7822f 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/DUtilCtxt.kt +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/DUtilCtxt.kt @@ -105,11 +105,15 @@ class DUtilCtxt { fun store(key: String, data: ByteArray?) { // Log.d( TAG, "store(key=%s)", key ); - if (null != data) { - DBUtils.setBytesFor(m_context, key, data) + data?.let { + DBUtils.setBytesFor(m_context, key, it) if (BuildConfig.DEBUG) { - val tmp = load(key) - Assert.assertTrue(tmp.contentEquals(data)) + val tmp = load(key)!! + if (! tmp.contentEquals(it)) { + Log.d(TAG, "store($key): race or bad content?; lens" + + " are ${tmp.size} and ${it.size}") + Assert.failDbg() + } } } } diff --git a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.kt b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.kt index 1b2ac5d70..bcd9b6b5b 100644 --- a/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.kt +++ b/xwords4/android/app/src/main/java/org/eehouse/android/xw4/jni/XwJNI.kt @@ -200,6 +200,25 @@ class XwJNI private constructor() { ACK_INVITE } + enum class STAT { + STAT_NONE, + STAT_MQTT_RCVD, + STAT_MQTT_SENT, + + STAT_REG_NOROOM, + + STAT_NEW_SOLO, + STAT_NEW_TWO, + STAT_NEW_THREE, + STAT_NEW_FOUR, + STAT_NEW_REMATCH, + + STAT_SMS_RCVD, + STAT_SMS_SENT, + + STAT_NSTATS, + } + class SMSProtoMsg { @JvmField var cmd: SMS_CMD? = null @@ -889,9 +908,8 @@ class XwJNI private constructor() { val str = sts_export(jNI.m_ptrGlobals) return JSONObject(str) } - - @JvmStatic fun sts_clearAll() { sts_clearAll(jNI.m_ptrGlobals) } + fun sts_increment(stat: STAT) {sts_increment(jNI.m_ptrGlobals, stat)} @JvmStatic external fun dict_tilesAreSame(dict1: Long, dict2: Long): Boolean @@ -1137,9 +1155,11 @@ class XwJNI private constructor() { ): Array? @JvmStatic - private external fun sts_export(jniState: Long): String? + private external fun sts_export(jniState: Long): String @JvmStatic private external fun sts_clearAll(jniState: Long) + @JvmStatic + private external fun sts_increment(jniState: Long, stat: STAT) // This always returns true on release builds now. @JvmStatic diff --git a/xwords4/android/jni/xwjni.c b/xwords4/android/jni/xwjni.c index 5e48bc3f7..00fe1bab7 100644 --- a/xwords4/android/jni/xwjni.c +++ b/xwords4/android/jni/xwjni.c @@ -1238,15 +1238,23 @@ Java_org_eehouse_android_xw4_jni_XwJNI_sts_1export return result; } -JNIEXPORT jstring JNICALL +JNIEXPORT void JNICALL Java_org_eehouse_android_xw4_jni_XwJNI_sts_1clearAll ( JNIEnv* env, jclass C, jlong jniGlobalPtr ) { - jstring result = NULL; DVC_HEADER(jniGlobalPtr); sts_clearAll( globalState->dutil, env ); DVC_HEADER_END(); - return result; +} + +JNIEXPORT void JNICALL +Java_org_eehouse_android_xw4_jni_XwJNI_sts_1increment +( JNIEnv* env, jclass C, jlong jniGlobalPtr, jobject jstat ) +{ + DVC_HEADER(jniGlobalPtr); + STAT stat = (STAT)jEnumToInt( env, jstat ); + sts_increment( globalState->dutil, env, stat ); + DVC_HEADER_END(); } /* Dictionary methods: don't use gamePtr */ diff --git a/xwords4/common/stats.c b/xwords4/common/stats.c index d063f5bf0..b8ab47e58 100644 --- a/xwords4/common/stats.c +++ b/xwords4/common/stats.c @@ -61,10 +61,10 @@ sts_increment( XW_DUtilCtxt* dutil, XWEnv xwe, STAT stat ) ss->statsVals = loadCounts( dutil, xwe ); } ++ss->statsVals[stat]; - END_WITH_MUTEX(); XP_LOGFF( "bad: storing after every change" ); storeCounts( dutil, xwe ); + END_WITH_MUTEX(); } } @@ -98,8 +98,19 @@ sts_export( XW_DUtilCtxt* dutil, XWEnv xwe ) /* } */ void -sts_clearAll( XW_DUtilCtxt* XP_UNUSED(dutil), XWEnv XP_UNUSED(xwe) ) +sts_clearAll( XW_DUtilCtxt* dutil, XWEnv xwe ) { + StatsState* ss = dutil->statsState; + XP_ASSERT( !!ss ); + + WITH_MUTEX( &ss->mutex ); + XP_FREEP( dutil->mpool, &ss->statsVals ); + + ss->statsVals + = XP_CALLOC( dutil->mpool, sizeof(*ss->statsVals) * STAT_NSTATS ); + END_WITH_MUTEX(); + + storeCounts( dutil, xwe ); } static const XP_UCHAR*