Skip to content

Commit

Permalink
stop using controller-clusters.zap in zap_generate_all (#26948)
Browse files Browse the repository at this point in the history
* separate out zap input, so we have control over it

* Switch zcl_clusters on for python

* Fix more loops to use the generic non-zap helpers

* Switch zap generate to use zcl

* update generate.py and change CHIPClientCallbacks.zapt

* Restyled by autopep8

* Fix another comment location

* Remove import from optional to make linter happy

* Skip restyling java generated files

* Run zap_regen_all

* Fix restyle path to include a glob

* Switch global callbacks to jinja

* update unit tests

* Fix global logic and codegen

* Codegen updated, validated that global callbacks is now identical

* Fix lint issue

* Update codegen logic to not depend on zap for src/controller/java/templates/ClusterInfo-java.zapt

* Also fix src/controller/java/templates/ChipClusters-java.zapt

* Use ANDROID_NDK_HOME env even for newer gradle build as the environment variable itself was deprecated (see https://github.com/android/ndk-samples/wiki/Configure-NDK-Path#android_ndk_home)

* Fixed indent a bit

* Updated comments a bit about controller-clusters.zap

* Be explicit on matter file name on codegen

* Remove duplicate output name

* Fix file path for CHIPClientCallbacks.h

* Update scripts/tools/zap_regen_all.py

Co-authored-by: Boris Zbarsky <[email protected]>

* Do some renames and code review updates

---------

Co-authored-by: Andrei Litvin <[email protected]>
Co-authored-by: Restyled.io <[email protected]>
Co-authored-by: Boris Zbarsky <[email protected]>
  • Loading branch information
4 people authored and pull[bot] committed Sep 22, 2023
1 parent b39775b commit 8a128e1
Show file tree
Hide file tree
Showing 15 changed files with 2,367 additions and 857 deletions.
1 change: 1 addition & 0 deletions examples/android/CHIPTest/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ println 'matterUTestLib='+matterUTestLib
android {
compileSdkVersion 30
buildToolsVersion "30.0.3"
ndkPath System.getenv("ANDROID_NDK_HOME")

defaultConfig {
applicationId "com.tcl.chip.chiptest"
Expand Down
1 change: 1 addition & 0 deletions examples/android/CHIPTool/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ apply plugin: 'kotlin-parcelize'

android {
compileSdkVersion 31
ndkPath System.getenv("ANDROID_NDK_HOME")

ndkVersion "23.2.8568313"

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
#include <jni.h>
#include <jni/CHIPReadCallbacks.h>
#include <lib/support/JniReferences.h>
#include <lib/support/JniTypeWrappers.h>
#include <lib/support/CodeUtils.h>
#include <lib/support/SafeInt.h>
#include <platform/PlatformManager.h>
#include <controller/java/zap-generated/CHIPClientCallbacks.h>

{% for type in globalTypes -%}
{%- set typeLookup = idl | createLookupContext(None) -%}
{%- set encodable = type.idl_type | globalAsEncodable(typeLookup) -%}
CHIP{{type.name}}AttributeCallback::CHIP{{type.name}}AttributeCallback(jobject javaCallback, bool keepAlive) :
chip::Callback::Callback<{{type.name}}AttributeCallback>(CallbackFn, this), keepAlive(keepAlive)
{
JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
if (env == nullptr) {
ChipLogError(Zcl, "Could not create global reference for Java callback");
return;
}
javaCallbackRef = env->NewGlobalRef(javaCallback);
if (javaCallbackRef == nullptr) {
ChipLogError(Zcl, "Could not create global reference for Java callback");
}
}

CHIP{{type.name}}AttributeCallback::~CHIP{{type.name}}AttributeCallback() {
JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
if (env == nullptr)
{
ChipLogError(Zcl, "Could not delete global reference for Java callback");
return;
}
env->DeleteGlobalRef(javaCallbackRef);
}

void CHIP{{type.name}}AttributeCallback::CallbackFn(void * context, {{type.cpp_type}} value)
{
chip::DeviceLayer::StackUnlock unlock;
CHIP_ERROR err = CHIP_NO_ERROR;

JNIEnv * env = chip::JniReferences::GetInstance().GetEnvForCurrentThread();
VerifyOrReturn(env != nullptr, ChipLogError(Zcl, "Could not get JNI env"));

std::unique_ptr<CHIP{{type.name}}AttributeCallback, decltype(&maybeDestroy)> cppCallback(reinterpret_cast<CHIP{{type.name}}AttributeCallback *>(context), maybeDestroy);

// It's valid for javaCallbackRef to be nullptr if the Java code passed in a
// null callback.
jobject javaCallbackRef = cppCallback.get()->javaCallbackRef;
VerifyOrReturn(javaCallbackRef != nullptr, ChipLogDetail(Zcl, "Early return from attribute callback since Java callback is null"));

jmethodID javaMethod;
{%- if encodable.is_octet_string %}
err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "([B)V", &javaMethod);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess method"));

VerifyOrReturn(chip::CanCastTo<uint32_t>(value.size()), ChipLogError(Zcl, "Value too long"));
jbyteArray valueArr = env->NewByteArray(static_cast<uint32_t>(value.size()));
env->ExceptionClear();
env->SetByteArrayRegion(valueArr, 0, static_cast<uint32_t>(value.size()), reinterpret_cast<const jbyte *>(value.data()));

env->CallVoidMethod(javaCallbackRef, javaMethod, valueArr);
{%- elif encodable.is_char_string %}
err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "(Ljava/lang/String;)V", &javaMethod);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess method"));

chip::UtfString valueStr(env, value);
env->CallVoidMethod(javaCallbackRef, javaMethod, valueStr.jniValue());
{%- else %}
err = chip::JniReferences::GetInstance().FindMethod(env, javaCallbackRef, "onSuccess", "({{encodable.unboxed_java_signature}})V", &javaMethod);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Zcl, "Could not find onSuccess method"));
env->CallVoidMethod(javaCallbackRef, javaMethod, static_cast<{{encodable.jni_fundamental_type}}>(value));
{%- endif %}
}

{% endfor %}
84 changes: 68 additions & 16 deletions scripts/py_matter_idl/matter_idl/generators/java/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,25 +35,26 @@ class GenerateTarget:

@dataclasses.dataclass
class GlobalType:
name: str # java name
name: str # java name
cpp_type: str # underlying type
idl_type: str # assumed IDL type


# types that java should see globally
_GLOBAL_TYPES = [
GlobalType("Boolean", "bool"),
GlobalType("CharString", "const chip::CharSpan"),
GlobalType("Double", "double"),
GlobalType("Float", "float"),
GlobalType("Int8s", "int8_t"),
GlobalType("Int8u", "uint8_t"),
GlobalType("Int16s", "int16_t"),
GlobalType("Int16u", "uint16_t"),
GlobalType("Int32s", "int32_t"),
GlobalType("Int32u", "uint32_t"),
GlobalType("Int64s", "int64_t"),
GlobalType("Int64u", "uint64_t"),
GlobalType("OctetString", "const chip::ByteSpan"),
GlobalType("Boolean", "bool", "boolean"),
GlobalType("CharString", "const chip::CharSpan", "char_string"),
GlobalType("Double", "double", "double"),
GlobalType("Float", "float", "single"),
GlobalType("Int8s", "int8_t", "int8s"),
GlobalType("Int8u", "uint8_t", "int8u"),
GlobalType("Int16s", "int16_t", "int16s"),
GlobalType("Int16u", "uint16_t", "int16u"),
GlobalType("Int32s", "int32_t", "int32s"),
GlobalType("Int32u", "uint32_t", "int32u"),
GlobalType("Int64s", "int64_t", "int64s"),
GlobalType("Int64u", "uint64_t", "int64u"),
GlobalType("OctetString", "const chip::ByteSpan", "octet_string"),
]


Expand Down Expand Up @@ -423,6 +424,23 @@ def get_underlying_enum(self):
raise Exception("Enum %s not found" % self.data_type.name)
return e

@property
def jni_fundamental_type(self):
java_type = self.boxed_java_type

if java_type == 'Boolean':
return 'jboolean'
elif java_type == 'Float':
return 'jfloat'
elif java_type == 'Double':
return 'jdouble'
elif java_type == 'Long':
return 'jlong'
elif java_type == 'Integer':
return 'jint'

raise Exception("Unknown jni fundamental type.")

@property
def boxed_java_type(self):
t = ParseDataType(self.data_type, self.context)
Expand Down Expand Up @@ -460,6 +478,30 @@ def boxed_java_type(self):
else:
return "Object"

@property
def unboxed_java_signature(self):
if self.is_optional or self.is_list:
raise Exception("Not a basic type: %r" % self)

t = ParseDataType(self.data_type, self.context)

if isinstance(t, FundamentalType):
if t == FundamentalType.BOOL:
return "Z"
elif t == FundamentalType.FLOAT:
return "F"
elif t == FundamentalType.DOUBLE:
return "D"
else:
raise Exception("Unknown fundamental type")
elif isinstance(t, BasicInteger):
if t.byte_count >= 3:
return "J"
else:
return "I"
else:
raise Exception("Not a basic type: %r" % self)

@property
def boxed_java_signature(self):
# Optional takes precedence over list - Optional<ArrayList> compiles down to just java.util.Optional.
Expand Down Expand Up @@ -504,6 +546,13 @@ def boxed_java_signature(self):
return "Lchip/devicecontroller/ChipStructs${}Cluster{};".format(self.context.cluster.name, self.data_type.name)


def GlobalEncodableValueFrom(typeName: str, context: TypeLookupContext) -> EncodableValue:
"""
Filter to convert a global type name to an encodable value
"""
return EncodableValue(context, DataType(name=typeName), {})


def EncodableValueFrom(field: Field, context: TypeLookupContext) -> EncodableValue:
"""
Filter to convert a standard field to an EncodableValue.
Expand All @@ -526,7 +575,7 @@ def EncodableValueFrom(field: Field, context: TypeLookupContext) -> EncodableVal
return EncodableValue(context, field.data_type, attrs)


def CreateLookupContext(idl: Idl, cluster: Cluster) -> TypeLookupContext:
def CreateLookupContext(idl: Idl, cluster: Optional[Cluster]) -> TypeLookupContext:
"""
A filter to mark a lookup context to be within a specific cluster.
Expand Down Expand Up @@ -579,6 +628,7 @@ def __init__(self, storage: GeneratorStorage, idl: Idl, **kargs):
self.jinja_env.filters['toBoxedJavaType'] = ToBoxedJavaType
self.jinja_env.filters['lowercaseFirst'] = LowercaseFirst
self.jinja_env.filters['asEncodable'] = EncodableValueFrom
self.jinja_env.filters['globalAsEncodable'] = GlobalEncodableValueFrom
self.jinja_env.filters['createLookupContext'] = CreateLookupContext
self.jinja_env.filters['canGenerateSubscribe'] = CanGenerateSubscribe
self.jinja_env.filters['decodableJniType'] = DecodableJniType
Expand All @@ -602,7 +652,9 @@ def internal_render_all(self):
GenerateTarget(template="CHIPCallbackTypes.jinja",
output_name="jni/CHIPCallbackTypes.h"),
GenerateTarget(template="CHIPReadCallbacks_h.jinja",
output_name="jni/CHIPReadCallbacks.h")
output_name="jni/CHIPReadCallbacks.h"),
GenerateTarget(template="CHIPGlobalCallbacks_cpp.jinja",
output_name="jni/CHIPGlobalCallbacks.cpp"),
]

for target in large_targets:
Expand Down
5 changes: 5 additions & 0 deletions scripts/py_matter_idl/matter_idl/tests/available_tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,21 @@ java-jni:
jni/MyClusterClient-InvokeSubscribeImpl.cpp: outputs/simple_attribute/jni/MyClusterClient-InvokeSubscribeImpl.cpp
jni/CHIPCallbackTypes.h: outputs/simple_attribute/jni/CHIPCallbackTypes.h
jni/CHIPReadCallbacks.h: outputs/simple_attribute/jni/CHIPReadReadCallbacks.h
jni/CHIPGlobalCallbacks.cpp: outputs/shared/jni/CHIPGlobalCallbacks.cpp

inputs/global_struct_attribute.matter:
jni/DemoClusterClient-ReadImpl.cpp: outputs/global_struct_attribute/jni/DemoClusterClient-ReadImpl.cpp
jni/DemoClusterClient-InvokeSubscribeImpl.cpp: outputs/global_struct_attribute/jni/DemoClusterClient-InvokeSubscribeImpl.cpp
jni/CHIPCallbackTypes.h: outputs/global_struct_attribute/jni/CHIPCallbackTypes.h
jni/CHIPReadCallbacks.h: outputs/global_struct_attribute/jni/CHIPReadReadCallbacks.h
jni/CHIPGlobalCallbacks.cpp: outputs/shared/jni/CHIPGlobalCallbacks.cpp

inputs/cluster_struct_attribute.matter:
jni/DemoClusterClient-ReadImpl.cpp: outputs/cluster_struct_attribute/jni/DemoClusterClient-ReadImpl.cpp
jni/DemoClusterClient-InvokeSubscribeImpl.cpp: outputs/cluster_struct_attribute/jni/DemoClusterClient-InvokeSubscribeImpl.cpp
jni/CHIPCallbackTypes.h: outputs/cluster_struct_attribute/jni/CHIPCallbackTypes.h
jni/CHIPReadCallbacks.h: outputs/cluster_struct_attribute/jni/CHIPReadReadCallbacks.h
jni/CHIPGlobalCallbacks.cpp: outputs/shared/jni/CHIPGlobalCallbacks.cpp

inputs/several_clusters.matter:
jni/FirstClient-ReadImpl.cpp: outputs/several_clusters/jni/FirstClient-ReadImpl.cpp
Expand All @@ -38,12 +41,14 @@ java-jni:
jni/ThirdClient-InvokeSubscribeImpl.cpp: outputs/several_clusters/jni/ThirdClient-InvokeSubscribeImpl.cpp
jni/CHIPCallbackTypes.h: outputs/several_clusters/jni/CHIPCallbackTypes.h
jni/CHIPReadCallbacks.h: outputs/several_clusters/jni/CHIPReadReadCallbacks.h
jni/CHIPGlobalCallbacks.cpp: outputs/shared/jni/CHIPGlobalCallbacks.cpp

inputs/optional_argument.matter:
jni/MyClusterClient-ReadImpl.cpp: outputs/optional_argument/jni/MyClusterClient-ReadImpl.cpp
jni/MyClusterClient-InvokeSubscribeImpl.cpp: outputs/optional_argument/jni/MyClusterClient-InvokeSubscribeImpl.cpp
jni/CHIPCallbackTypes.h: outputs/optional_argument/jni/CHIPCallbackTypes.h
jni/CHIPReadCallbacks.h: outputs/optional_argument/jni/CHIPReadReadCallbacks.h
jni/CHIPGlobalCallbacks.cpp: outputs/shared/jni/CHIPGlobalCallbacks.cpp

java-class:
inputs/several_clusters.matter:
Expand Down
Loading

0 comments on commit 8a128e1

Please sign in to comment.