diff --git a/src/app/server/java/BUILD.gn b/src/app/server/java/BUILD.gn index 166cdd82ade5a2..905257607e7178 100644 --- a/src/app/server/java/BUILD.gn +++ b/src/app/server/java/BUILD.gn @@ -27,6 +27,8 @@ static_library("jni") { "AndroidAppServerWrapper.cpp", "AndroidAppServerWrapper.h", "CHIPAppServer-JNI.cpp", + "ChipFabricProvider-JNI.cpp", + "ChipFabricProvider-JNI.h", "ChipThreadWork.cpp", "ChipThreadWork.h", ] @@ -59,6 +61,8 @@ android_library("java") { sources = [ "src/chip/appserver/ChipAppServer.java", "src/chip/appserver/ChipAppServerException.java", + "src/chip/appserver/ChipFabricProvider.java", + "src/chip/appserver/Fabric.java", ] javac_flags = [ "-Xlint:deprecation" ] diff --git a/src/app/server/java/CHIPAppServer-JNI.cpp b/src/app/server/java/CHIPAppServer-JNI.cpp index 52f9a55c78a947..de7109a7245165 100644 --- a/src/app/server/java/CHIPAppServer-JNI.cpp +++ b/src/app/server/java/CHIPAppServer-JNI.cpp @@ -22,6 +22,7 @@ * */ #include "AndroidAppServerWrapper.h" +#include "ChipFabricProvider-JNI.h" #include "ChipThreadWork.h" #include #include @@ -80,6 +81,8 @@ jint AndroidAppServerJNI_OnLoad(JavaVM * jvm, void * reserved) err = AndroidChipPlatformJNI_OnLoad(jvm, reserved); SuccessOrExit(err); + err = AndroidChipFabricProviderJNI_OnLoad(jvm, reserved); + SuccessOrExit(err); exit: if (err != CHIP_NO_ERROR) diff --git a/src/app/server/java/ChipFabricProvider-JNI.cpp b/src/app/server/java/ChipFabricProvider-JNI.cpp new file mode 100644 index 00000000000000..ae7aac3ce75af0 --- /dev/null +++ b/src/app/server/java/ChipFabricProvider-JNI.cpp @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * 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. + * + */ + +/** + * @file + * Implementation of JNI bridge for CHIP App Server for Android TV apps + * + */ +#include "ChipFabricProvider-JNI.h" +#include "AndroidAppServerWrapper.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace chip; + +#define JNI_METHOD(RETURN, METHOD_NAME) extern "C" JNIEXPORT RETURN JNICALL Java_chip_appserver_ChipFabricProvider_##METHOD_NAME + +namespace { +JavaVM * sJVM; +} // namespace + +CHIP_ERROR AndroidChipFabricProviderJNI_OnLoad(JavaVM * jvm, void * reserved) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + JNIEnv * env; + + ChipLogProgress(DeviceLayer, "ChipFabricProvider JNI_OnLoad() called"); + + chip::Platform::MemoryInit(); + + // Save a reference to the JVM. Will need this to call back into Java. + JniReferences::GetInstance().SetJavaVm(jvm, "chip/appserver/ChipFabricProvider"); + sJVM = jvm; + + // check if the JNI environment is correct + env = JniReferences::GetInstance().GetEnvForCurrentThread(); + VerifyOrExit(env != NULL, err = CHIP_JNI_ERROR_NO_ENV); + + chip::InitializeTracing(); + +exit: + if (err != CHIP_NO_ERROR) + { + JNI_OnUnload(jvm, reserved); + } + + return err; +} + +void AndroidChipFabricProviderJNI_OnUnload(JavaVM * jvm, void * reserved) +{ + ChipLogProgress(DeviceLayer, "ChipFabricProvider JNI_OnUnload() called"); + chip::Platform::MemoryShutdown(); +} + +CHIP_ERROR ReadFabricList(JNIEnv * env, jobject & self) +{ + CHIP_ERROR err = CHIP_NO_ERROR; + jclass jFabricCls = env->FindClass("chip/appserver/Fabric"); + VerifyOrExit(self != nullptr, err = CHIP_JNI_ERROR_NULL_OBJECT); + VerifyOrExit(jFabricCls != nullptr, ChipLogError(NotSpecified, "could not find Class Fabric")); + for (auto & fabricInfo : Server::GetInstance().GetFabricTable()) + { + + jmethodID constructor = env->GetMethodID(jFabricCls, "", "()V"); + VerifyOrExit(constructor != nullptr, err = CHIP_JNI_ERROR_METHOD_NOT_FOUND); + jobject jFabric = env->NewObject(jFabricCls, constructor); + VerifyOrExit(!env->ExceptionCheck(), err = CHIP_JNI_ERROR_EXCEPTION_THROWN); + jfieldID jvendorId = env->GetFieldID(jFabricCls, "vendorId", "I"); + VerifyOrExit(jvendorId != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND); + jfieldID jnodeId = env->GetFieldID(jFabricCls, "nodeId", "J"); + VerifyOrExit(jnodeId != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND); + jfieldID jfabricIndex = env->GetFieldID(jFabricCls, "fabricIndex", "S"); + VerifyOrExit(jfabricIndex != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND); + jfieldID jlabel = env->GetFieldID(jFabricCls, "label", "Ljava/lang/String;"); + VerifyOrExit(jlabel != nullptr, err = CHIP_JNI_ERROR_FIELD_NOT_FOUND); + + env->SetIntField(jFabric, jvendorId, fabricInfo.GetVendorId()); + env->SetLongField(jFabric, jnodeId, fabricInfo.GetNodeId()); + env->SetShortField(jFabric, jfabricIndex, fabricInfo.GetFabricIndex()); + UtfString jLabelStr(env, fabricInfo.GetFabricLabel()); + env->SetObjectField(jFabric, jlabel, jLabelStr.jniValue()); + + JniReferences::GetInstance().AddToList(self, jFabric); + } + +exit: + return err; +} + +JNI_METHOD(jint, getFabricCount)(JNIEnv * env, jobject self) +{ + // a simplified way to get fabric count,see /src/credentials/FabricTable.h#FabricCount + return chip::Server::GetInstance().GetFabricTable().FabricCount(); +} + +JNI_METHOD(jobject, getFabricList)(JNIEnv * env, jobject self) +{ + jobject jFabricList; + JniReferences::GetInstance().CreateArrayList(jFabricList); + ReadFabricList(env, jFabricList); + return jFabricList; +} diff --git a/src/app/server/java/ChipFabricProvider-JNI.h b/src/app/server/java/ChipFabricProvider-JNI.h new file mode 100644 index 00000000000000..384442da601d4d --- /dev/null +++ b/src/app/server/java/ChipFabricProvider-JNI.h @@ -0,0 +1,28 @@ +/* + * + * Copyright (c) 2022 Project CHIP Authors + * + * 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. + */ + +#pragma once + +#include +#include +#include + +CHIP_ERROR AndroidChipFabricProviderJNI_OnLoad(JavaVM * jvm, void * reserved); + +void AndroidChipFabricProviderJNI_OnUnload(JavaVM * jvm, void * reserved); + +CHIP_ERROR ReadFabricList(JNIEnv * env, jobject & self); diff --git a/src/app/server/java/src/chip/appserver/ChipAppServer.java b/src/app/server/java/src/chip/appserver/ChipAppServer.java index a954dc1f9d8379..4b414070a12fcf 100644 --- a/src/app/server/java/src/chip/appserver/ChipAppServer.java +++ b/src/app/server/java/src/chip/appserver/ChipAppServer.java @@ -21,6 +21,19 @@ public class ChipAppServer { private static final String TAG = ChipAppServer.class.getSimpleName(); + private volatile ChipFabricProvider mChipFabricProvider; + + public ChipFabricProvider getFabricProvider() { + + if (mChipFabricProvider == null) { + synchronized (this) { + if (mChipFabricProvider == null) mChipFabricProvider = new ChipFabricProvider(); + } + } + + return mChipFabricProvider; + } + public native boolean startApp(); public native boolean stopApp(); diff --git a/src/app/server/java/src/chip/appserver/ChipFabricProvider.java b/src/app/server/java/src/chip/appserver/ChipFabricProvider.java new file mode 100644 index 00000000000000..bbb61a674d555c --- /dev/null +++ b/src/app/server/java/src/chip/appserver/ChipFabricProvider.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * 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. + * + */ +package chip.appserver; + +import java.util.List; + +/** read fabric count and list */ +public class ChipFabricProvider { + public native int getFabricCount(); + + public native List getFabricList(); + + // todo support to remove fabric +} diff --git a/src/app/server/java/src/chip/appserver/Fabric.java b/src/app/server/java/src/chip/appserver/Fabric.java new file mode 100644 index 00000000000000..71e391659cc804 --- /dev/null +++ b/src/app/server/java/src/chip/appserver/Fabric.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022 Project CHIP Authors + * All rights reserved. + * + * 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. + * + */ +package chip.appserver; + +public class Fabric { + + public int vendorId; + public long nodeId; + public short fabricIndex; + public String label; + + @Override + public String toString() { + return "Fabric [fabricIndex=" + + fabricIndex + + ", label=" + + label + + ", nodeId=" + + nodeId + + ", vendorId=" + + vendorId + + "]"; + } +}