Skip to content

Commit

Permalink
[Android] Replace GetMethodID with FindMethod for method retrieval (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
yufengwangca authored and pull[bot] committed Jan 22, 2024
1 parent 9d3c2e7 commit 97dfbeb
Show file tree
Hide file tree
Showing 8 changed files with 2,202 additions and 1,175 deletions.
10 changes: 7 additions & 3 deletions src/controller/java/templates/CHIPEventTLVValueDecoder-src.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,13 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader &
ChipLogError(Zcl, "Could not find class ChipEventStructs${{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}Event");
return nullptr;
}
jmethodID {{asLowerCamelCase name}}StructCtor = env->GetMethodID({{asLowerCamelCase name}}StructClass, "<init>"
, "({{#zcl_event_fields}}{{asJniSignature type null (asUpperCamelCase parent.parent.name) true}}{{/zcl_event_fields}})V");
if ({{asLowerCamelCase name}}StructCtor == nullptr) {

jmethodID {{asLowerCamelCase name}}StructCtor;
err = chip::JniReferences::GetInstance().FindMethod(
env, {{asLowerCamelCase name}}StructClass, "<init>",
"({{#zcl_event_fields}}{{asJniSignature type null (asUpperCamelCase parent.parent.name) true}}{{/zcl_event_fields}})V",
&{{asLowerCamelCase name}}StructCtor);
if (err != CHIP_NO_ERROR || {{asLowerCamelCase name}}StructCtor == nullptr) {
ChipLogError(Zcl, "Could not find ChipEventStructs${{asUpperCamelCase parent.name}}Cluster{{asUpperCamelCase name}}Event constructor");
return nullptr;
}
Expand Down
10 changes: 7 additions & 3 deletions src/controller/java/templates/partials/decode_value.zapt
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ if ({{source}}.IsNull()) {
ChipLogError(Zcl, "Could not find class ChipStructs${{asUpperCamelCase cluster}}Cluster{{asUpperCamelCase type}}");
return {{earlyReturn}};
}
jmethodID {{asLowerCamelCase type}}StructCtor_{{depth}} = env->GetMethodID({{asLowerCamelCase type}}StructClass_{{depth}}, "<init>"
, "({{#zcl_struct_items_by_struct_and_cluster_name type cluster}}{{asJniSignature type null (asUpperCamelCase ../cluster) true}}{{/zcl_struct_items_by_struct_and_cluster_name}})V");
if ({{asLowerCamelCase type}}StructCtor_{{depth}} == nullptr) {

jmethodID {{asLowerCamelCase type}}StructCtor_{{depth}};
err = chip::JniReferences::GetInstance().FindMethod(
env, {{asLowerCamelCase type}}StructClass_{{depth}}, "<init>",
"({{#zcl_struct_items_by_struct_and_cluster_name type cluster}}{{asJniSignature type null (asUpperCamelCase ../cluster) true}}{{/zcl_struct_items_by_struct_and_cluster_name}})V",
&{{asLowerCamelCase type}}StructCtor_{{depth}});
if (err != CHIP_NO_ERROR || {{asLowerCamelCase type}}StructCtor_{{depth}} == nullptr) {
ChipLogError(Zcl, "Could not find ChipStructs${{asUpperCamelCase cluster}}Cluster{{asUpperCamelCase type}} constructor");
return {{earlyReturn}};
}
Expand Down
1,129 changes: 728 additions & 401 deletions src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp

Large diffs are not rendered by default.

1,073 changes: 713 additions & 360 deletions src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp

Large diffs are not rendered by default.

307 changes: 196 additions & 111 deletions src/controller/java/zap-generated/CHIPInvokeCallbacks.cpp

Large diffs are not rendered by default.

790 changes: 507 additions & 283 deletions src/controller/java/zap-generated/CHIPReadCallbacks.cpp

Large diffs are not rendered by default.

54 changes: 40 additions & 14 deletions src/lib/support/JniReferences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <lib/support/CodeUtils.h>
#include <lib/support/JniReferences.h>
#include <lib/support/JniTypeWrappers.h>
#include <string>

namespace chip {

Expand All @@ -35,7 +36,7 @@ void JniReferences::SetJavaVm(JavaVM * jvm, const char * clsType)
JNIEnv * env = GetEnvForCurrentThread();
// Any chip.devicecontroller.* class will work here - just need something to call getClassLoader() on.
jclass chipClass = env->FindClass(clsType);
VerifyOrReturn(chipClass != nullptr, ChipLogError(Support, "clsType can not found"));
VerifyOrReturn(chipClass != nullptr, ChipLogError(Support, "clsType can not be found"));

jclass classClass = env->FindClass("java/lang/Class");
jclass classLoaderClass = env->FindClass("java/lang/ClassLoader");
Expand Down Expand Up @@ -129,6 +130,19 @@ CHIP_ERROR JniReferences::N2J_ByteArray(JNIEnv * env, const uint8_t * inArray, j
return err;
}

static std::string StrReplaceAll(const std::string & source, const std::string & from, const std::string & to)
{
std::string newString = source;
size_t pos = 0;
while ((pos = newString.find(from, pos)) != std::string::npos)
{
newString.replace(pos, from.length(), to);
pos += to.length();
}

return newString;
}

CHIP_ERROR JniReferences::FindMethod(JNIEnv * env, jobject object, const char * methodName, const char * methodSignature,
jmethodID * methodId)
{
Expand All @@ -146,23 +160,35 @@ CHIP_ERROR JniReferences::FindMethod(JNIEnv * env, jobject object, const char *
return CHIP_NO_ERROR;
}

// Try `j$` when enabling Java8.
std::string methodSignature_java8_str(methodSignature);
size_t pos = methodSignature_java8_str.find("java/util/Optional");
if (pos != std::string::npos)
std::string method_signature = methodSignature;
method_signature = StrReplaceAll(method_signature, "java/util/Optional", "j$/util/Optional");
*methodId = env->GetMethodID(javaClass, methodName, method_signature.data());
env->ExceptionClear();

VerifyOrReturnError(*methodId != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);
return CHIP_NO_ERROR;
}

CHIP_ERROR JniReferences::FindMethod(JNIEnv * env, jclass javaClass, const char * methodName, const char * methodSignature,
jmethodID * methodId)
{
VerifyOrReturnError(env != nullptr, CHIP_JNI_ERROR_NULL_OBJECT);
VerifyOrReturnError(javaClass != nullptr, CHIP_JNI_ERROR_TYPE_NOT_FOUND);

*methodId = env->GetMethodID(javaClass, methodName, methodSignature);
env->ExceptionClear();

if (*methodId != nullptr)
{
// Replace all "java/util/Optional" with "j$/util/Optional".
while (pos != std::string::npos)
{
methodSignature_java8_str.replace(pos, strlen("java/util/Optional"), "j$/util/Optional");
pos = methodSignature_java8_str.find("java/util/Optional");
}
*methodId = env->GetMethodID(javaClass, methodName, methodSignature_java8_str.c_str());
env->ExceptionClear();
return CHIP_NO_ERROR;
}

VerifyOrReturnError(*methodId != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);
std::string method_signature = methodSignature;
method_signature = StrReplaceAll(method_signature, "java/util/Optional", "j$/util/Optional");
*methodId = env->GetMethodID(javaClass, methodName, method_signature.data());
env->ExceptionClear();

VerifyOrReturnError(*methodId != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);
return CHIP_NO_ERROR;
}

Expand Down
4 changes: 4 additions & 0 deletions src/lib/support/JniReferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ class JniReferences

CHIP_ERROR FindMethod(JNIEnv * env, jobject object, const char * methodName, const char * methodSignature,
jmethodID * methodId);

CHIP_ERROR FindMethod(JNIEnv * env, jclass javaClass, const char * methodName, const char * methodSignature,
jmethodID * methodId);

void CallVoidInt(JNIEnv * env, jobject object, const char * methodName, jint argument);

CHIP_ERROR N2J_ByteArray(JNIEnv * env, const uint8_t * inArray, jsize inArrayLen, jbyteArray & outArray);
Expand Down

0 comments on commit 97dfbeb

Please sign in to comment.