Support int32_t (Java Integer) in KeyValuePair atom

Bug: 116826451
Test: statsd_test + manual verification through logcat
Change-Id: I0157c22033907fea46e26ee4262c723fa8c0b518
diff --git a/cmds/statsd/src/atoms.proto b/cmds/statsd/src/atoms.proto
index 1e9c354..16cb7ac 100644
--- a/cmds/statsd/src/atoms.proto
+++ b/cmds/statsd/src/atoms.proto
@@ -200,9 +200,10 @@
 message KeyValuePair {
     optional int32 key = 1;
     oneof value {
-        int64 value_int = 2;
-        string value_str = 3;
-        float value_float = 4;
+        int32 value_int = 2;
+        int64 value_long = 3;
+        string value_str = 4;
+        float value_float = 5;
     }
 }
 
diff --git a/cmds/statsd/src/logd/LogEvent.cpp b/cmds/statsd/src/logd/LogEvent.cpp
index f9f1b38..3afa08f 100644
--- a/cmds/statsd/src/logd/LogEvent.cpp
+++ b/cmds/statsd/src/logd/LogEvent.cpp
@@ -92,7 +92,8 @@
 
 LogEvent::LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
                    int32_t uid,
-                   const std::map<int32_t, int64_t>& int_map,
+                   const std::map<int32_t, int32_t>& int_map,
+                   const std::map<int32_t, int64_t>& long_map,
                    const std::map<int32_t, std::string>& string_map,
                    const std::map<int32_t, float>& float_map) {
     mLogdTimestampNs = wallClockTimestampNs;
@@ -113,7 +114,7 @@
         pos[1]++;
     }
 
-    for (const auto&itr : string_map) {
+    for (const auto&itr : long_map) {
         pos[2] = 1;
         mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
         pos[2] = 3;
@@ -122,7 +123,7 @@
         pos[1]++;
     }
 
-    for (const auto&itr : float_map) {
+    for (const auto&itr : string_map) {
         pos[2] = 1;
         mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
         pos[2] = 4;
@@ -130,6 +131,15 @@
         mValues.back().mField.decorateLastPos(2);
         pos[1]++;
     }
+
+    for (const auto&itr : float_map) {
+        pos[2] = 1;
+        mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.first)));
+        pos[2] = 5;
+        mValues.push_back(FieldValue(Field(mTagId, pos, 2 /* depth */), Value(itr.second)));
+        mValues.back().mField.decorateLastPos(2);
+        pos[1]++;
+    }
     if (!mValues.empty()) {
         mValues.back().mField.decorateLastPos(1);
         mValues.at(mValues.size() - 2).mField.decorateLastPos(1);
@@ -215,7 +225,8 @@
 
 
 
-bool LogEvent::writeKeyValuePairs(const std::map<int32_t, int64_t>& int_map,
+bool LogEvent::writeKeyValuePairs(const std::map<int32_t, int32_t>& int_map,
+                                  const std::map<int32_t, int64_t>& long_map,
                                   const std::map<int32_t, std::string>& string_map,
                                   const std::map<int32_t, float>& float_map) {
     if (mContext) {
@@ -233,6 +244,17 @@
              }
          }
 
+         for (const auto& itr : long_map) {
+             if (android_log_write_list_begin(mContext) < 0) {
+                return false;
+             }
+             write(itr.first);
+             write(itr.second);
+             if (android_log_write_list_end(mContext) < 0) {
+                return false;
+             }
+         }
+
          for (const auto& itr : string_map) {
              if (android_log_write_list_begin(mContext) < 0) {
                 return false;
diff --git a/cmds/statsd/src/logd/LogEvent.h b/cmds/statsd/src/logd/LogEvent.h
index 9ef0bf4..0a8ac2b 100644
--- a/cmds/statsd/src/logd/LogEvent.h
+++ b/cmds/statsd/src/logd/LogEvent.h
@@ -77,7 +77,8 @@
      */
     explicit LogEvent(int32_t tagId, int64_t wallClockTimestampNs, int64_t elapsedTimestampNs,
                       int32_t uid,
-                      const std::map<int32_t, int64_t>& int_map,
+                      const std::map<int32_t, int32_t>& int_map,
+                      const std::map<int32_t, int64_t>& long_map,
                       const std::map<int32_t, std::string>& string_map,
                       const std::map<int32_t, float>& float_map);
 
@@ -122,7 +123,8 @@
     bool write(float value);
     bool write(const std::vector<AttributionNodeInternal>& nodes);
     bool write(const AttributionNodeInternal& node);
-    bool writeKeyValuePairs(const std::map<int32_t, int64_t>& int_map,
+    bool writeKeyValuePairs(const std::map<int32_t, int32_t>& int_map,
+                            const std::map<int32_t, int64_t>& long_map,
                             const std::map<int32_t, std::string>& string_map,
                             const std::map<int32_t, float>& float_map);
 
diff --git a/cmds/statsd/tests/LogEvent_test.cpp b/cmds/statsd/tests/LogEvent_test.cpp
index 6e3b04c..d490701 100644
--- a/cmds/statsd/tests/LogEvent_test.cpp
+++ b/cmds/statsd/tests/LogEvent_test.cpp
@@ -91,12 +91,16 @@
 
 TEST(LogEventTest, TestKeyValuePairsAtomParsing) {
     LogEvent event1(83, 2000);
-    std::map<int32_t, int64_t> int_map;
+    std::map<int32_t, int32_t> int_map;
+    std::map<int32_t, int64_t> long_map;
     std::map<int32_t, std::string> string_map;
     std::map<int32_t, float> float_map;
 
-    int_map[11] = 123L;
-    int_map[22] = 345L;
+    int_map[11] = 123;
+    int_map[22] = 345;
+
+    long_map[33] = 678L;
+    long_map[44] = 890L;
 
     string_map[1] = "test2";
     string_map[2] = "test1";
@@ -104,12 +108,15 @@
     float_map[111] = 2.2f;
     float_map[222] = 1.1f;
 
-    EXPECT_TRUE(event1.writeKeyValuePairs(int_map, string_map, float_map));
+    EXPECT_TRUE(event1.writeKeyValuePairs(int_map,
+                                          long_map,
+                                          string_map,
+                                          float_map));
     event1.init();
 
     EXPECT_EQ(83, event1.GetTagId());
     const auto& items = event1.getValues();
-    EXPECT_EQ((size_t)12, items.size());
+    EXPECT_EQ((size_t)16, items.size());
 
     const FieldValue& item0 = event1.getValues()[0];
     EXPECT_EQ(0x2010101, item0.mField.getField());
@@ -118,8 +125,8 @@
 
     const FieldValue& item1 = event1.getValues()[1];
     EXPECT_EQ(0x2010182, item1.mField.getField());
-    EXPECT_EQ(Type::LONG, item1.mValue.getType());
-    EXPECT_EQ(123L, item1.mValue.long_value);
+    EXPECT_EQ(Type::INT, item1.mValue.getType());
+    EXPECT_EQ(123, item1.mValue.int_value);
 
     const FieldValue& item2 = event1.getValues()[2];
     EXPECT_EQ(0x2010201, item2.mField.getField());
@@ -128,48 +135,68 @@
 
     const FieldValue& item3 = event1.getValues()[3];
     EXPECT_EQ(0x2010282, item3.mField.getField());
-    EXPECT_EQ(Type::LONG, item3.mValue.getType());
-    EXPECT_EQ(345L, item3.mValue.long_value);
+    EXPECT_EQ(Type::INT, item3.mValue.getType());
+    EXPECT_EQ(345, item3.mValue.int_value);
 
     const FieldValue& item4 = event1.getValues()[4];
     EXPECT_EQ(0x2010301, item4.mField.getField());
     EXPECT_EQ(Type::INT, item4.mValue.getType());
-    EXPECT_EQ(1, item4.mValue.int_value);
+    EXPECT_EQ(33, item4.mValue.int_value);
 
     const FieldValue& item5 = event1.getValues()[5];
-    EXPECT_EQ(0x2010383, item5.mField.getField());
-    EXPECT_EQ(Type::STRING, item5.mValue.getType());
-    EXPECT_EQ("test2", item5.mValue.str_value);
+    EXPECT_EQ(0x2010382, item5.mField.getField());
+    EXPECT_EQ(Type::LONG, item5.mValue.getType());
+    EXPECT_EQ(678L, item5.mValue.int_value);
 
     const FieldValue& item6 = event1.getValues()[6];
     EXPECT_EQ(0x2010401, item6.mField.getField());
     EXPECT_EQ(Type::INT, item6.mValue.getType());
-    EXPECT_EQ(2, item6.mValue.int_value);
+    EXPECT_EQ(44, item6.mValue.int_value);
 
     const FieldValue& item7 = event1.getValues()[7];
-    EXPECT_EQ(0x2010483, item7.mField.getField());
-    EXPECT_EQ(Type::STRING, item7.mValue.getType());
-    EXPECT_EQ("test1", item7.mValue.str_value);
+    EXPECT_EQ(0x2010482, item7.mField.getField());
+    EXPECT_EQ(Type::LONG, item7.mValue.getType());
+    EXPECT_EQ(890L, item7.mValue.int_value);
 
     const FieldValue& item8 = event1.getValues()[8];
     EXPECT_EQ(0x2010501, item8.mField.getField());
     EXPECT_EQ(Type::INT, item8.mValue.getType());
-    EXPECT_EQ(111, item8.mValue.int_value);
+    EXPECT_EQ(1, item8.mValue.int_value);
 
     const FieldValue& item9 = event1.getValues()[9];
-    EXPECT_EQ(0x2010584, item9.mField.getField());
-    EXPECT_EQ(Type::FLOAT, item9.mValue.getType());
-    EXPECT_EQ(2.2f, item9.mValue.float_value);
+    EXPECT_EQ(0x2010583, item9.mField.getField());
+    EXPECT_EQ(Type::STRING, item9.mValue.getType());
+    EXPECT_EQ("test2", item9.mValue.str_value);
 
     const FieldValue& item10 = event1.getValues()[10];
-    EXPECT_EQ(0x2018601, item10.mField.getField());
+    EXPECT_EQ(0x2010601, item10.mField.getField());
     EXPECT_EQ(Type::INT, item10.mValue.getType());
-    EXPECT_EQ(222, item10.mValue.int_value);
+    EXPECT_EQ(2, item10.mValue.int_value);
 
     const FieldValue& item11 = event1.getValues()[11];
-    EXPECT_EQ(0x2018684, item11.mField.getField());
-    EXPECT_EQ(Type::FLOAT, item11.mValue.getType());
-    EXPECT_EQ(1.1f, item11.mValue.float_value);
+    EXPECT_EQ(0x2010683, item11.mField.getField());
+    EXPECT_EQ(Type::STRING, item11.mValue.getType());
+    EXPECT_EQ("test1", item11.mValue.str_value);
+
+    const FieldValue& item12 = event1.getValues()[12];
+    EXPECT_EQ(0x2010701, item12.mField.getField());
+    EXPECT_EQ(Type::INT, item12.mValue.getType());
+    EXPECT_EQ(111, item12.mValue.int_value);
+
+    const FieldValue& item13 = event1.getValues()[13];
+    EXPECT_EQ(0x2010784, item13.mField.getField());
+    EXPECT_EQ(Type::FLOAT, item13.mValue.getType());
+    EXPECT_EQ(2.2f, item13.mValue.float_value);
+
+    const FieldValue& item14 = event1.getValues()[14];
+    EXPECT_EQ(0x2018801, item14.mField.getField());
+    EXPECT_EQ(Type::INT, item14.mValue.getType());
+    EXPECT_EQ(222, item14.mValue.int_value);
+
+    const FieldValue& item15 = event1.getValues()[15];
+    EXPECT_EQ(0x2018884, item15.mField.getField());
+    EXPECT_EQ(Type::FLOAT, item15.mValue.getType());
+    EXPECT_EQ(1.1f, item15.mValue.float_value);
 }
 
 TEST(LogEventTest, TestLogParsing2) {
@@ -242,12 +269,16 @@
 }
 
 TEST(LogEventTest, TestKeyValuePairsEvent) {
-    std::map<int32_t, int64_t> int_map;
+    std::map<int32_t, int32_t> int_map;
+    std::map<int32_t, int64_t> long_map;
     std::map<int32_t, std::string> string_map;
     std::map<int32_t, float> float_map;
 
-    int_map[11] = 123L;
-    int_map[22] = 345L;
+    int_map[11] = 123;
+    int_map[22] = 345;
+
+    long_map[33] = 678L;
+    long_map[44] = 890L;
 
     string_map[1] = "test2";
     string_map[2] = "test1";
@@ -255,7 +286,7 @@
     float_map[111] = 2.2f;
     float_map[222] = 1.1f;
 
-    LogEvent event1(83, 2000, 2001, 10001, int_map, string_map, float_map);
+    LogEvent event1(83, 2000, 2001, 10001, int_map, long_map, string_map, float_map);
     event1.init();
 
     EXPECT_EQ(83, event1.GetTagId());
@@ -263,7 +294,7 @@
     EXPECT_EQ((int64_t)2001, event1.GetElapsedTimestampNs());
 
     const auto& items = event1.getValues();
-    EXPECT_EQ((size_t)13, items.size());
+    EXPECT_EQ((size_t)17, items.size());
 
     const FieldValue& item0 = event1.getValues()[0];
     EXPECT_EQ(0x00010000, item0.mField.getField());
@@ -277,8 +308,8 @@
 
     const FieldValue& item2 = event1.getValues()[2];
     EXPECT_EQ(0x2020182, item2.mField.getField());
-    EXPECT_EQ(Type::LONG, item2.mValue.getType());
-    EXPECT_EQ(123L, item2.mValue.long_value);
+    EXPECT_EQ(Type::INT, item2.mValue.getType());
+    EXPECT_EQ(123, item2.mValue.int_value);
 
     const FieldValue& item3 = event1.getValues()[3];
     EXPECT_EQ(0x2020201, item3.mField.getField());
@@ -287,48 +318,68 @@
 
     const FieldValue& item4 = event1.getValues()[4];
     EXPECT_EQ(0x2020282, item4.mField.getField());
-    EXPECT_EQ(Type::LONG, item4.mValue.getType());
-    EXPECT_EQ(345L, item4.mValue.long_value);
+    EXPECT_EQ(Type::INT, item4.mValue.getType());
+    EXPECT_EQ(345, item4.mValue.int_value);
 
     const FieldValue& item5 = event1.getValues()[5];
     EXPECT_EQ(0x2020301, item5.mField.getField());
     EXPECT_EQ(Type::INT, item5.mValue.getType());
-    EXPECT_EQ(1, item5.mValue.int_value);
+    EXPECT_EQ(33, item5.mValue.int_value);
 
     const FieldValue& item6 = event1.getValues()[6];
-    EXPECT_EQ(0x2020383, item6.mField.getField());
-    EXPECT_EQ(Type::STRING, item6.mValue.getType());
-    EXPECT_EQ("test2", item6.mValue.str_value);
+    EXPECT_EQ(0x2020382, item6.mField.getField());
+    EXPECT_EQ(Type::LONG, item6.mValue.getType());
+    EXPECT_EQ(678L, item6.mValue.long_value);
 
     const FieldValue& item7 = event1.getValues()[7];
     EXPECT_EQ(0x2020401, item7.mField.getField());
     EXPECT_EQ(Type::INT, item7.mValue.getType());
-    EXPECT_EQ(2, item7.mValue.int_value);
+    EXPECT_EQ(44, item7.mValue.int_value);
 
     const FieldValue& item8 = event1.getValues()[8];
-    EXPECT_EQ(0x2020483, item8.mField.getField());
-    EXPECT_EQ(Type::STRING, item8.mValue.getType());
-    EXPECT_EQ("test1", item8.mValue.str_value);
+    EXPECT_EQ(0x2020482, item8.mField.getField());
+    EXPECT_EQ(Type::LONG, item8.mValue.getType());
+    EXPECT_EQ(890L, item8.mValue.long_value);
 
     const FieldValue& item9 = event1.getValues()[9];
     EXPECT_EQ(0x2020501, item9.mField.getField());
     EXPECT_EQ(Type::INT, item9.mValue.getType());
-    EXPECT_EQ(111, item9.mValue.int_value);
+    EXPECT_EQ(1, item9.mValue.int_value);
 
     const FieldValue& item10 = event1.getValues()[10];
-    EXPECT_EQ(0x2020584, item10.mField.getField());
-    EXPECT_EQ(Type::FLOAT, item10.mValue.getType());
-    EXPECT_EQ(2.2f, item10.mValue.float_value);
+    EXPECT_EQ(0x2020583, item10.mField.getField());
+    EXPECT_EQ(Type::STRING, item10.mValue.getType());
+    EXPECT_EQ("test2", item10.mValue.str_value);
 
     const FieldValue& item11 = event1.getValues()[11];
-    EXPECT_EQ(0x2028601, item11.mField.getField());
+    EXPECT_EQ(0x2020601, item11.mField.getField());
     EXPECT_EQ(Type::INT, item11.mValue.getType());
-    EXPECT_EQ(222, item11.mValue.int_value);
+    EXPECT_EQ(2, item11.mValue.int_value);
 
     const FieldValue& item12 = event1.getValues()[12];
-    EXPECT_EQ(0x2028684, item12.mField.getField());
-    EXPECT_EQ(Type::FLOAT, item12.mValue.getType());
-    EXPECT_EQ(1.1f, item12.mValue.float_value);
+    EXPECT_EQ(0x2020683, item12.mField.getField());
+    EXPECT_EQ(Type::STRING, item12.mValue.getType());
+    EXPECT_EQ("test1", item12.mValue.str_value);
+
+    const FieldValue& item13 = event1.getValues()[13];
+    EXPECT_EQ(0x2020701, item13.mField.getField());
+    EXPECT_EQ(Type::INT, item13.mValue.getType());
+    EXPECT_EQ(111, item13.mValue.int_value);
+
+    const FieldValue& item14 = event1.getValues()[14];
+    EXPECT_EQ(0x2020784, item14.mField.getField());
+    EXPECT_EQ(Type::FLOAT, item14.mValue.getType());
+    EXPECT_EQ(2.2f, item14.mValue.float_value);
+
+    const FieldValue& item15 = event1.getValues()[15];
+    EXPECT_EQ(0x2028801, item15.mField.getField());
+    EXPECT_EQ(Type::INT, item15.mValue.getType());
+    EXPECT_EQ(222, item15.mValue.int_value);
+
+    const FieldValue& item16 = event1.getValues()[16];
+    EXPECT_EQ(0x2028884, item16.mField.getField());
+    EXPECT_EQ(Type::FLOAT, item16.mValue.getType());
+    EXPECT_EQ(1.1f, item16.mValue.float_value);
 }
 
 
@@ -337,4 +388,4 @@
 }  // namespace android
 #else
 GTEST_LOG_(INFO) << "This test does nothing.\n";
-#endif
\ No newline at end of file
+#endif
diff --git a/tools/stats_log_api_gen/main.cpp b/tools/stats_log_api_gen/main.cpp
index 9915479..56c8428 100644
--- a/tools/stats_log_api_gen/main.cpp
+++ b/tools/stats_log_api_gen/main.cpp
@@ -234,9 +234,11 @@
                     }
                 }
             } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
-                fprintf(out, ", const std::map<int, int64_t>& arg%d_1, "
-                             "const std::map<int, char const*>& arg%d_2, "
-                             "const std::map<int, float>& arg%d_3", argIndex, argIndex, argIndex);
+                fprintf(out, ", const std::map<int, int32_t>& arg%d_1, "
+                             "const std::map<int, int64_t>& arg%d_2, "
+                             "const std::map<int, char const*>& arg%d_3, "
+                             "const std::map<int, float>& arg%d_4",
+                             argIndex, argIndex, argIndex, argIndex);
             } else {
                 fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
             }
@@ -302,6 +304,13 @@
                     fprintf(out, "         event.end();\n");
                     fprintf(out, "    }\n");
 
+                    fprintf(out, "    for (const auto& it : arg%d_4) {\n", argIndex);
+                    fprintf(out, "         event.begin();\n");
+                    fprintf(out, "         event << it.first;\n");
+                    fprintf(out, "         event << it.second;\n");
+                    fprintf(out, "         event.end();\n");
+                    fprintf(out, "    }\n");
+
                     fprintf(out, "    event.end();\n\n");
             } else {
                 if (*arg == JAVA_TYPE_STRING) {
@@ -344,9 +353,11 @@
                    }
                }
            } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
-                fprintf(out, ", const std::map<int, int64_t>& arg%d_1, "
-                             "const std::map<int, char const*>& arg%d_2, "
-                             "const std::map<int, float>& arg%d_3", argIndex, argIndex, argIndex);
+                fprintf(out, ", const std::map<int, int32_t>& arg%d_1, "
+                             "const std::map<int, int64_t>& arg%d_2, "
+                             "const std::map<int, char const*>& arg%d_3, "
+                             "const std::map<int, float>& arg%d_4",
+                             argIndex, argIndex, argIndex, argIndex);
            } else {
                fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
            }
@@ -374,7 +385,8 @@
                    }
                }
            } else  if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
-                fprintf(out, ", arg%d_1, arg%d_2, arg%d_3", argIndex, argIndex, argIndex);
+                fprintf(out, ", arg%d_1, arg%d_2, arg%d_3, arg%d_4",
+                        argIndex, argIndex, argIndex, argIndex);
            } else {
                fprintf(out, ", arg%d", argIndex);
            }
@@ -529,10 +541,14 @@
                 }
             }
         } else if (field->javaType == JAVA_TYPE_KEY_VALUE_PAIR) {
-            fprintf(out, ", const std::map<int, int64_t>& %s_int"
+            fprintf(out, ", const std::map<int, int32_t>& %s_int"
+                         ", const std::map<int, int64_t>& %s_long"
                          ", const std::map<int, char const*>& %s_str"
                          ", const std::map<int, float>& %s_float",
-                         field->name.c_str(), field->name.c_str(), field->name.c_str());
+                         field->name.c_str(),
+                         field->name.c_str(),
+                         field->name.c_str(),
+                         field->name.c_str());
         } else {
             fprintf(out, ", %s %s", cpp_type_name(field->javaType), field->name.c_str());
         }
@@ -561,9 +577,11 @@
                     }
                 }
             } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
-                fprintf(out, ", const std::map<int, int64_t>& arg%d_1, "
-                             "const std::map<int, char const*>& arg%d_2, "
-                             "const std::map<int, float>& arg%d_3", argIndex, argIndex, argIndex);
+                fprintf(out, ", const std::map<int, int32_t>& arg%d_1, "
+                             "const std::map<int, int64_t>& arg%d_2, "
+                             "const std::map<int, char const*>& arg%d_3, "
+                             "const std::map<int, float>& arg%d_4",
+                             argIndex, argIndex, argIndex, argIndex);
             } else {
                 fprintf(out, ", %s arg%d", cpp_type_name(*arg), argIndex);
             }
@@ -976,6 +994,7 @@
 }
 
 static void write_key_value_map_jni(FILE* out) {
+   fprintf(out, "    std::map<int, int32_t> int32_t_map;\n");
    fprintf(out, "    std::map<int, int64_t> int64_t_map;\n");
    fprintf(out, "    std::map<int, float> float_map;\n");
    fprintf(out, "    std::map<int, char const*> string_map;\n\n");
@@ -989,9 +1008,11 @@
 
    fprintf(out, "    std::vector<std::unique_ptr<ScopedUtfChars>> scoped_ufs;\n\n");
 
+   fprintf(out, "    jclass jint_class = env->FindClass(\"java/lang/Integer\");\n");
    fprintf(out, "    jclass jlong_class = env->FindClass(\"java/lang/Long\");\n");
    fprintf(out, "    jclass jfloat_class = env->FindClass(\"java/lang/Float\");\n");
    fprintf(out, "    jclass jstring_class = env->FindClass(\"java/lang/String\");\n");
+   fprintf(out, "    jmethodID jget_int_method = env->GetMethodID(jint_class, \"intValue\", \"()I\");\n");
    fprintf(out, "    jmethodID jget_long_method = env->GetMethodID(jlong_class, \"longValue\", \"()J\");\n");
    fprintf(out, "    jmethodID jget_float_method = env->GetMethodID(jfloat_class, \"floatValue\", \"()F\");\n\n");
 
@@ -1000,7 +1021,9 @@
    fprintf(out, "        jint key = env->CallIntMethod(value_map, jget_key_method, i);\n");
    fprintf(out, "        jobject jvalue_obj = env->CallObjectMethod(value_map, jget_value_method, i);\n");
    fprintf(out, "        if (jvalue_obj == NULL) { continue; }\n");
-   fprintf(out, "        if (env->IsInstanceOf(jvalue_obj, jlong_class)) {\n");
+   fprintf(out, "        if (env->IsInstanceOf(jvalue_obj, jint_class)) {\n");
+   fprintf(out, "            int32_t_map[key] = env->CallIntMethod(jvalue_obj, jget_int_method);\n");
+   fprintf(out, "        } else if (env->IsInstanceOf(jvalue_obj, jlong_class)) {\n");
    fprintf(out, "            int64_t_map[key] = env->CallLongMethod(jvalue_obj, jget_long_method);\n");
    fprintf(out, "        } else if (env->IsInstanceOf(jvalue_obj, jfloat_class)) {\n");
    fprintf(out, "            float_map[key] = env->CallFloatMethod(jvalue_obj, jget_float_method);\n");
@@ -1129,7 +1152,7 @@
                     }
                 }
             } else if (*arg == JAVA_TYPE_KEY_VALUE_PAIR) {
-                fprintf(out, ", int64_t_map, string_map, float_map");
+                fprintf(out, ", int32_t_map, int64_t_map, string_map, float_map");
             } else {
                 const char *argName = (*arg == JAVA_TYPE_STRING) ? "str" : "arg";
                 fprintf(out, ", (%s)%s%d", cpp_type_name(*arg), argName, argIndex);