Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Java] Remove duplicated implementation for ReportCallback #28541

Merged
merged 1 commit into from
Aug 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 0 additions & 18 deletions src/controller/java/AndroidCallbacks-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,24 +59,6 @@ JNI_METHOD(void, ReportCallbackJni, deleteCallback)(JNIEnv * env, jobject self,
chip::Platform::Delete(reportCallback);
}

JNI_METHOD(jlong, ReportEventCallbackJni, newCallback)
(JNIEnv * env, jobject self, jobject subscriptionEstablishedCallbackJava, jobject reportCallbackJava,
jobject resubscriptionAttemptCallbackJava)
{
chip::DeviceLayer::StackLock lock;
ReportEventCallback * reportCallback = chip::Platform::New<ReportEventCallback>(
self, subscriptionEstablishedCallbackJava, reportCallbackJava, resubscriptionAttemptCallbackJava);
return reinterpret_cast<jlong>(reportCallback);
}

JNI_METHOD(void, ReportEventCallbackJni, deleteCallback)(JNIEnv * env, jobject self, jlong callbackHandle)
{
chip::DeviceLayer::StackLock lock;
ReportEventCallback * reportCallback = reinterpret_cast<ReportEventCallback *>(callbackHandle);
VerifyOrReturn(reportCallback != nullptr, ChipLogError(Controller, "ReportCallback handle is nullptr"));
delete reportCallback;
}

JNI_METHOD(jlong, WriteAttributesCallbackJni, newCallback)
(JNIEnv * env, jobject self, jobject writeAttributesCallbackJava)
{
Expand Down
256 changes: 0 additions & 256 deletions src/controller/java/AndroidCallbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -612,262 +612,6 @@ void ReportCallback::ReportError(jobject attributePath, jobject eventPath, const
VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe());
}

ReportEventCallback::ReportEventCallback(jobject wrapperCallback, jobject subscriptionEstablishedCallback, jobject reportCallback,
jobject resubscriptionAttemptCallback) :
mBufferedReadAdapter(*this)
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
VerifyOrReturn(env != nullptr, ChipLogError(Controller, "Could not get JNIEnv for current thread"));
if (subscriptionEstablishedCallback != nullptr)
{
mSubscriptionEstablishedCallbackRef = env->NewGlobalRef(subscriptionEstablishedCallback);
if (mSubscriptionEstablishedCallbackRef == nullptr)
{
ChipLogError(Controller, "Could not create global reference for Java callback");
}
}
mReportCallbackRef = env->NewGlobalRef(reportCallback);
if (mReportCallbackRef == nullptr)
{
ChipLogError(Controller, "Could not create global reference for Java callback");
}
mWrapperCallbackRef = env->NewGlobalRef(wrapperCallback);
if (mWrapperCallbackRef == nullptr)
{
ChipLogError(Controller, "Could not create global reference for Java callback");
}
if (resubscriptionAttemptCallback != nullptr)
{
mResubscriptionAttemptCallbackRef = env->NewGlobalRef(resubscriptionAttemptCallback);
if (mResubscriptionAttemptCallbackRef == nullptr)
{
ChipLogError(Controller, "Could not create global reference for Java callback");
}
}
}

ReportEventCallback::~ReportEventCallback()
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
VerifyOrReturn(env != nullptr, ChipLogError(Controller, "Could not get JNIEnv for current thread"));
if (mSubscriptionEstablishedCallbackRef != nullptr)
{
env->DeleteGlobalRef(mSubscriptionEstablishedCallbackRef);
}
env->DeleteGlobalRef(mReportCallbackRef);
if (mReadClient != nullptr)
{
Platform::Delete(mReadClient);
}
}

void ReportEventCallback::OnReportBegin()
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
CHIP_ERROR err = CHIP_NO_ERROR;

err = JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/model/NodeState", mNodeStateCls);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Could not get NodeState class"));
jmethodID nodeStateCtor = env->GetMethodID(mNodeStateCls, "<init>", "(Ljava/util/Map;)V");
VerifyOrReturn(nodeStateCtor != nullptr, ChipLogError(Controller, "Could not find NodeState constructor"));

jobject map = nullptr;
err = JniReferences::GetInstance().CreateHashMap(map);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Could not create HashMap"));
mNodeStateObj = env->NewObject(mNodeStateCls, nodeStateCtor, map);
}

void ReportEventCallback::OnReportEnd()
{
// Transform C++ jobject pair list to a Java HashMap, and call onReport() on the Java callback.
CHIP_ERROR err = CHIP_NO_ERROR;
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();

jmethodID onReportMethod;
err = JniReferences::GetInstance().FindMethod(env, mReportCallbackRef, "onReport", "(Lchip/devicecontroller/model/NodeState;)V",
&onReportMethod);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Could not find onReport method"));

DeviceLayer::StackUnlock unlock;
env->CallVoidMethod(mReportCallbackRef, onReportMethod, mNodeStateObj);
}

void ReportEventCallback::OnEventData(const app::EventHeader & aEventHeader, TLV::TLVReader * apData,
const app::StatusIB * apStatus)
{
CHIP_ERROR err = CHIP_NO_ERROR;
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
jobject eventPathObj = nullptr;
err = CreateChipEventPath(aEventHeader.mPath, eventPathObj);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to create Java ChipEventPath: %s", ErrorStr(err)));

if (apData == nullptr)
{
ReportError(eventPathObj, CHIP_ERROR_INVALID_ARGUMENT);
return;
}

TLV::TLVReader readerForJavaTLV;
TLV::TLVReader readerForJson;
readerForJavaTLV.Init(*apData);
readerForJson.Init(*apData);

jlong eventNumber = static_cast<jlong>(aEventHeader.mEventNumber);
jlong priorityLevel = static_cast<jint>(aEventHeader.mPriorityLevel);
jlong timestamp = static_cast<jlong>(aEventHeader.mTimestamp.mValue);

jobject value = nullptr;
#if USE_JAVA_TLV_ENCODE_DECODE
TLV::TLVReader readerForJavaObject;
readerForJavaObject.Init(*apData);
value = DecodeEventValue(aEventHeader.mPath, readerForJavaObject, &err);
// If we don't know this event, just skip it.
VerifyOrReturn(err != CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB);
VerifyOrReturn(err == CHIP_NO_ERROR, ReportError(eventPathObj, err));
VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe(), ReportError(eventPathObj, CHIP_JNI_ERROR_EXCEPTION_THROWN));
#endif

// Create TLV byte array to pass to Java layer
size_t bufferLen = readerForJavaTLV.GetRemainingLength() + readerForJavaTLV.GetLengthRead();
std::unique_ptr<uint8_t[]> buffer = std::unique_ptr<uint8_t[]>(new uint8_t[bufferLen]);
uint32_t size = 0;
// The TLVReader's read head is not pointing to the first element in the container, instead of the container itself, use
// a TLVWriter to get a TLV with a normalized TLV buffer (Wrapped with an anonymous tag, no extra "end of container" tag
// at the end.)
TLV::TLVWriter writer;
writer.Init(buffer.get(), bufferLen);
err = writer.CopyElement(TLV::AnonymousTag(), readerForJavaTLV);
VerifyOrReturn(err == CHIP_NO_ERROR, ReportError(eventPathObj, err));
size = writer.GetLengthWritten();
chip::ByteArray jniByteArray(env, reinterpret_cast<jbyte *>(buffer.get()), size);

// Convert TLV to JSON
Json::Value json;
err = TlvToJson(readerForJson, json);
VerifyOrReturn(err == CHIP_NO_ERROR, ReportError(eventPathObj, err));

UtfString jsonString(env, JsonToString(json).c_str());

// Create EventState object
jclass eventStateCls;
err = JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/model/EventState", eventStateCls);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Could not find EventState class"));
VerifyOrReturn(eventStateCls != nullptr, ChipLogError(Controller, "Could not find EventState class"));
chip::JniClass eventStateJniCls(eventStateCls);
jmethodID eventStateCtor = env->GetMethodID(eventStateCls, "<init>", "(JIJLjava/lang/Object;[BLjava/lang/String;)V");
VerifyOrReturn(eventStateCtor != nullptr, ChipLogError(Controller, "Could not find EventState constructor"));
jobject eventStateObj = env->NewObject(eventStateCls, eventStateCtor, eventNumber, priorityLevel, timestamp, value,
jniByteArray.jniValue(), jsonString.jniValue());
VerifyOrReturn(eventStateObj != nullptr, ChipLogError(Controller, "Could not create EventState object"));

// Add EventState to NodeState
jmethodID addEventMethod;
err = JniReferences::GetInstance().FindMethod(env, mNodeStateObj, "addEvent", "(IJJLchip/devicecontroller/model/EventState;)V",
&addEventMethod);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Could not find addEvent method"));
env->CallVoidMethod(mNodeStateObj, addEventMethod, static_cast<jint>(aEventHeader.mPath.mEndpointId),
static_cast<jlong>(aEventHeader.mPath.mClusterId), static_cast<jlong>(aEventHeader.mPath.mEventId),
eventStateObj);
VerifyOrReturn(!env->ExceptionCheck(), env->ExceptionDescribe());
}

CHIP_ERROR ReportEventCallback::CreateChipEventPath(const app::ConcreteEventPath & aPath, jobject & outObj)
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
CHIP_ERROR err = CHIP_NO_ERROR;

jclass eventPathCls = nullptr;
err = JniReferences::GetInstance().GetClassRef(env, "chip/devicecontroller/model/ChipEventPath", eventPathCls);
VerifyOrReturnError(err == CHIP_NO_ERROR, err);
JniClass eventPathJniCls(eventPathCls);

jmethodID eventPathCtor =
env->GetStaticMethodID(eventPathCls, "newInstance", "(IJJ)Lchip/devicecontroller/model/ChipEventPath;");
VerifyOrReturnError(eventPathCtor != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);

outObj = env->CallStaticObjectMethod(eventPathCls, eventPathCtor, static_cast<jint>(aPath.mEndpointId),
static_cast<jlong>(aPath.mClusterId), static_cast<jlong>(aPath.mEventId));
VerifyOrReturnError(outObj != nullptr, CHIP_JNI_ERROR_NULL_OBJECT);

return err;
}

void ReportEventCallback::OnError(CHIP_ERROR aError)
{
ReportError(nullptr, aError);
}

void ReportEventCallback::OnDone(app::ReadClient *)
{
CHIP_ERROR err = CHIP_NO_ERROR;
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();

jmethodID onDoneMethod;
err = JniReferences::GetInstance().FindMethod(env, mReportCallbackRef, "onDone", "()V", &onDoneMethod);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Could not find onDone method"));

DeviceLayer::StackUnlock unlock;
env->CallVoidMethod(mReportCallbackRef, onDoneMethod);

JniReferences::GetInstance().GetEnvForCurrentThread()->DeleteGlobalRef(mWrapperCallbackRef);
}

void ReportEventCallback::OnSubscriptionEstablished(SubscriptionId aSubscriptionId)
{
chip::DeviceLayer::StackUnlock unlock;
JniReferences::GetInstance().CallSubscriptionEstablished(mSubscriptionEstablishedCallbackRef, aSubscriptionId);
}

CHIP_ERROR ReportEventCallback::OnResubscriptionNeeded(app::ReadClient * apReadClient, CHIP_ERROR aTerminationCause)
{
VerifyOrReturnLogError(mResubscriptionAttemptCallbackRef != nullptr, CHIP_ERROR_INVALID_ARGUMENT);

JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();

ReturnErrorOnFailure(app::ReadClient::Callback::OnResubscriptionNeeded(apReadClient, aTerminationCause));

jmethodID onResubscriptionAttemptMethod;
ReturnLogErrorOnFailure(JniReferences::GetInstance().FindMethod(
env, mResubscriptionAttemptCallbackRef, "onResubscriptionAttempt", "(JJ)V", &onResubscriptionAttemptMethod));

DeviceLayer::StackUnlock unlock;
env->CallVoidMethod(mResubscriptionAttemptCallbackRef, onResubscriptionAttemptMethod,
static_cast<jlong>(aTerminationCause.AsInteger()),
static_cast<jlong>(apReadClient->ComputeTimeTillNextSubscription()));

return CHIP_NO_ERROR;
}

void ReportEventCallback::ReportError(jobject eventPath, CHIP_ERROR err)
{
ReportError(eventPath, ErrorStr(err), err.AsInteger());
}

void ReportEventCallback::ReportError(jobject eventPath, Protocols::InteractionModel::Status status)
{
ReportError(eventPath, "IM Status", static_cast<std::underlying_type_t<Protocols::InteractionModel::Status>>(status));
}

void ReportEventCallback::ReportError(jobject eventPath, const char * message, ChipError::StorageType errorCode)
{
CHIP_ERROR err = CHIP_NO_ERROR;
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();

jthrowable exception;
err = AndroidControllerExceptions::GetInstance().CreateAndroidControllerException(env, message, errorCode, exception);
VerifyOrReturn(err == CHIP_NO_ERROR,
ChipLogError(Controller, "Unable to create AndroidControllerException: %s on eportEventCallback::ReportError",
ErrorStr(err)));

jmethodID onErrorMethod;
err = JniReferences::GetInstance().FindMethod(
env, mReportCallbackRef, "onError", "(Lchip/devicecontroller/model/ChipEventPath;Ljava/lang/Exception;)V", &onErrorMethod);
VerifyOrReturn(err == CHIP_NO_ERROR, ChipLogError(Controller, "Unable to find onError method: %s", ErrorStr(err)));

DeviceLayer::StackUnlock unlock;
env->CallVoidMethod(mReportCallbackRef, onErrorMethod, eventPath, exception);
}

WriteAttributesCallback::WriteAttributesCallback(jobject wrapperCallback, jobject javaCallback) : mChunkedWriteCallback(this)
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
Expand Down
2 changes: 0 additions & 2 deletions src/controller/java/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -345,8 +345,6 @@ android_library("java") {
"src/chip/devicecontroller/PaseVerifierParams.java",
"src/chip/devicecontroller/ReportCallback.java",
"src/chip/devicecontroller/ReportCallbackJni.java",
"src/chip/devicecontroller/ReportEventCallback.java",
"src/chip/devicecontroller/ReportEventCallbackJni.java",
"src/chip/devicecontroller/ResubscriptionAttemptCallback.java",
"src/chip/devicecontroller/SubscriptionEstablishedCallback.java",
"src/chip/devicecontroller/ThreadScanResult.java",
Expand Down

This file was deleted.

This file was deleted.