Skip to content

Commit

Permalink
[Android] Apply 'AppDelegate' for android app server (#28286)
Browse files Browse the repository at this point in the history
* Apply 'AppDelegate' for android app server

* Add 'starAppWithDelegate' api
* Add 'ChipAppServerDelegate' interface

Signed-off-by: Jaehoon You <jaehoon.you@samsung.com>
Signed-off-by: Charles Kim <chulspro.kim@samsung.com>

* Restyled by whitespace

* Restyled by google-java-format

* Restyled by clang-format

Signed-off-by: Charles Kim <chulspro.kim@samsung.com>

* Restyled by google-java-format

Signed-off-by: Charles Kim <chulspro.kim@samsung.com>

---------

Signed-off-by: Jaehoon You <jaehoon.you@samsung.com>
Signed-off-by: Charles Kim <chulspro.kim@samsung.com>
Co-authored-by: Jaehoon You <jaehoon.you@samsung.com>
Co-authored-by: Restyled.io <commits@restyled.io>
  • Loading branch information
3 people authored Jul 27, 2023
1 parent d7a7dee commit 2b76339
Show file tree
Hide file tree
Showing 9 changed files with 321 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.matter.virtual.device.app.core.matter

import chip.appserver.ChipAppServer
import chip.appserver.ChipAppServerDelegate
import javax.inject.Inject
import javax.inject.Singleton
import timber.log.Timber

@Singleton
class MatterApp @Inject constructor() {

private var chipAppServer: ChipAppServer? = null

fun start() {
chipAppServer = ChipAppServer()
chipAppServer?.startAppWithDelegate(
object : ChipAppServerDelegate {
override fun onCommissioningSessionEstablishmentStarted() {
Timber.d("onCommissioningSessionEstablishmentStarted()")
}

override fun onCommissioningSessionStarted() {
Timber.d("onCommissioningSessionStarted()")
}

override fun onCommissioningSessionEstablishmentError(errorCode: Int) {
Timber.d("onCommissioningSessionEstablishmentError():$errorCode")
}

override fun onCommissioningSessionStopped() {
Timber.d("onCommissioningSessionStopped()")
}

override fun onCommissioningWindowOpened() {
Timber.d("onCommissioningWindowOpened()")
}

override fun onCommissioningWindowClosed() {
Timber.d("onCommissioningWindowClosed()")
}
}
)
}

fun stop() {
chipAppServer?.stopApp()
}
}
7 changes: 6 additions & 1 deletion src/app/server/java/AndroidAppServerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ using namespace chip::Inet;
using namespace chip::Transport;
using namespace chip::DeviceLayer;

CHIP_ERROR ChipAndroidAppInit(void)
CHIP_ERROR ChipAndroidAppInit(AppDelegate * appDelegate)
{
CHIP_ERROR err = CHIP_NO_ERROR;

Expand All @@ -50,6 +50,11 @@ CHIP_ERROR ChipAndroidAppInit(void)
// Init ZCL Data Model and CHIP App Server
static chip::CommonCaseDeviceServerInitParams initParams;
(void) initParams.InitializeStaticResourcesBeforeServerInit();
if (appDelegate != nullptr)
{
initParams.appDelegate = appDelegate;
}

initParams.operationalServicePort = CHIP_PORT;
initParams.userDirectedCommissioningPort = CHIP_UDC_PORT;

Expand Down
3 changes: 2 additions & 1 deletion src/app/server/java/AndroidAppServerWrapper.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
*/

#pragma once
#include <app/server/AppDelegate.h>
#include <jni.h>
#include <lib/core/CHIPError.h>

CHIP_ERROR ChipAndroidAppInit(void);
CHIP_ERROR ChipAndroidAppInit(AppDelegate * appDelegate = nullptr);

void ChipAndroidAppShutdown(void);

Expand Down
3 changes: 3 additions & 0 deletions src/app/server/java/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ static_library("jni") {
"AndroidAppServerWrapper.cpp",
"AndroidAppServerWrapper.h",
"CHIPAppServer-JNI.cpp",
"ChipAppServerDelegate.cpp",
"ChipAppServerDelegate.h",
"ChipFabricProvider-JNI.cpp",
"ChipFabricProvider-JNI.h",
"ChipThreadWork.cpp",
Expand Down Expand Up @@ -62,6 +64,7 @@ android_library("java") {

sources = [
"src/chip/appserver/ChipAppServer.java",
"src/chip/appserver/ChipAppServerDelegate.java",
"src/chip/appserver/ChipAppServerException.java",
"src/chip/appserver/ChipFabricProvider.java",
"src/chip/appserver/Fabric.java",
Expand Down
25 changes: 25 additions & 0 deletions src/app/server/java/CHIPAppServer-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
*
*/
#include "AndroidAppServerWrapper.h"
#include "ChipAppServerDelegate.h"
#include "ChipFabricProvider-JNI.h"
#include "ChipThreadWork.h"
#include <jni.h>
Expand Down Expand Up @@ -53,6 +54,7 @@ namespace {
JavaVM * sJVM;
pthread_t sIOThread = PTHREAD_NULL;
jclass sChipAppServerExceptionCls = NULL;
ChipAppServerDelegate sChipAppServerDelegate;
} // namespace

jint AndroidAppServerJNI_OnLoad(JavaVM * jvm, void * reserved)
Expand Down Expand Up @@ -134,6 +136,29 @@ JNI_METHOD(jboolean, startApp)(JNIEnv * env, jobject self)
return JNI_TRUE;
}

JNI_METHOD(jboolean, startAppWithDelegate)(JNIEnv * env, jobject self, jobject appDelegate)
{
chip::DeviceLayer::StackLock lock;

CHIP_ERROR err = sChipAppServerDelegate.InitializeWithObjects(appDelegate);
SuccessOrExit(err);

err = ChipAndroidAppInit(&sChipAppServerDelegate);
SuccessOrExit(err);

if (sIOThread == PTHREAD_NULL)
{
pthread_create(&sIOThread, NULL, IOThreadAppMain, NULL);
}

exit:
if (err != CHIP_NO_ERROR)
{
return JNI_FALSE;
}
return JNI_TRUE;
}

JNI_METHOD(jboolean, stopApp)(JNIEnv * env, jobject self)
{
chip::ThreadWork::ChipMainThreadScheduleAndWait([] { ChipAndroidAppShutdown(); });
Expand Down
159 changes: 159 additions & 0 deletions src/app/server/java/ChipAppServerDelegate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/*
*
* Copyright (c) 2023 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.
*/

#include "ChipAppServerDelegate.h"
#include <lib/support/CHIPJNIError.h>
#include <lib/support/JniReferences.h>

using namespace chip;

void ChipAppServerDelegate::OnCommissioningSessionEstablishmentStarted()
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
VerifyOrReturn(env != nullptr, ChipLogError(AppServer, "JNIEnv is nullptr"));
VerifyOrReturn(mOnCommissioningSessionEstablishmentStartedMethod != nullptr,
ChipLogError(AppServer, "mOnCommissioningSessionEstablishmentStartedMethod is nullptr"));

env->ExceptionClear();
env->CallVoidMethod(mChipAppServerDelegateObject, mOnCommissioningSessionEstablishmentStartedMethod);
if (env->ExceptionCheck())
{
ChipLogError(AppServer, "Java exception in OnCommissioningSessionEstablishmentStartedMethod");
env->ExceptionDescribe();
env->ExceptionClear();
}
}

void ChipAppServerDelegate::OnCommissioningSessionStarted()
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
VerifyOrReturn(env != nullptr, ChipLogError(AppServer, "JNIEnv is nullptr"));
VerifyOrReturn(mOnCommissioningSessionStartedMethod != nullptr,
ChipLogError(AppServer, "mOnCommissioningSessionStartedMethod is nullptr"));

env->ExceptionClear();
env->CallVoidMethod(mChipAppServerDelegateObject, mOnCommissioningSessionStartedMethod);
if (env->ExceptionCheck())
{
ChipLogError(AppServer, "Java exception in OnCommissioningSessionStartedMethod");
env->ExceptionDescribe();
env->ExceptionClear();
}
}

void ChipAppServerDelegate::OnCommissioningSessionEstablishmentError(CHIP_ERROR err)
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
VerifyOrReturn(env != nullptr, ChipLogError(AppServer, "JNIEnv is nullptr"));
VerifyOrReturn(mOnCommissioningSessionEstablishmentErrorMethod != nullptr,
ChipLogError(AppServer, "mOnCommissioningSessionEstablishmentErrorMethod is nullptr"));

env->ExceptionClear();
env->CallVoidMethod(mChipAppServerDelegateObject, mOnCommissioningSessionEstablishmentErrorMethod,
static_cast<jint>(err.AsInteger()));
if (env->ExceptionCheck())
{
ChipLogError(AppServer, "Java exception in OnCommissioningSessionEstablishmentErrorMethod");
env->ExceptionDescribe();
env->ExceptionClear();
}
}

void ChipAppServerDelegate::OnCommissioningSessionStopped()
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
VerifyOrReturn(env != nullptr, ChipLogError(AppServer, "JNIEnv is nullptr"));
VerifyOrReturn(mOnCommissioningSessionStoppedMethod != nullptr,
ChipLogError(AppServer, "mOnCommissioningSessionStoppedMethod is nullptr"));

env->ExceptionClear();
env->CallVoidMethod(mChipAppServerDelegateObject, mOnCommissioningSessionStoppedMethod);
if (env->ExceptionCheck())
{
ChipLogError(AppServer, "Java exception in OnCommissioningSessionStoppedMethod");
env->ExceptionDescribe();
env->ExceptionClear();
}
}

void ChipAppServerDelegate::OnCommissioningWindowOpened()
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
VerifyOrReturn(env != nullptr, ChipLogError(AppServer, "JNIEnv is nullptr"));
VerifyOrReturn(mOnCommissioningWindowOpenedMethod != nullptr,
ChipLogError(AppServer, "mOnCommissioningWindowOpenedMethod is nullptr"));

env->ExceptionClear();
env->CallVoidMethod(mChipAppServerDelegateObject, mOnCommissioningWindowOpenedMethod);
if (env->ExceptionCheck())
{
ChipLogError(AppServer, "Java exception in OnCommissioningWindowOpenedMethod");
env->ExceptionDescribe();
env->ExceptionClear();
}
}

void ChipAppServerDelegate::OnCommissioningWindowClosed()
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
VerifyOrReturn(env != nullptr, ChipLogError(AppServer, "JNIEnv is nullptr"));
VerifyOrReturn(mOnCommissioningWindowClosedMethod != nullptr,
ChipLogError(AppServer, "mOnCommissioningWindowClosedMethod is nullptr"));

env->ExceptionClear();
env->CallVoidMethod(mChipAppServerDelegateObject, mOnCommissioningWindowClosedMethod);
if (env->ExceptionCheck())
{
ChipLogError(AppServer, "Java exception in OnCommissioningWindowClosedMethod");
env->ExceptionDescribe();
env->ExceptionClear();
}
}

CHIP_ERROR ChipAppServerDelegate::InitializeWithObjects(jobject appDelegateObject)
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
VerifyOrReturnLogError(env != nullptr, CHIP_JNI_ERROR_NO_ENV);

mChipAppServerDelegateObject = env->NewGlobalRef(appDelegateObject);
VerifyOrReturnLogError(mChipAppServerDelegateObject != nullptr, CHIP_JNI_ERROR_NULL_OBJECT);

jclass chipAppServerDelegateClass = env->GetObjectClass(mChipAppServerDelegateObject);
VerifyOrReturnLogError(chipAppServerDelegateClass != nullptr, CHIP_JNI_ERROR_JAVA_ERROR);

mOnCommissioningSessionEstablishmentStartedMethod =
env->GetMethodID(chipAppServerDelegateClass, "onCommissioningSessionEstablishmentStarted", "()V");
VerifyOrReturnLogError(mOnCommissioningSessionEstablishmentStartedMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);

mOnCommissioningSessionStartedMethod = env->GetMethodID(chipAppServerDelegateClass, "onCommissioningSessionStarted", "()V");
VerifyOrReturnLogError(mOnCommissioningSessionStartedMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);

mOnCommissioningSessionEstablishmentErrorMethod =
env->GetMethodID(chipAppServerDelegateClass, "onCommissioningSessionEstablishmentError", "(I)V");
VerifyOrReturnLogError(mOnCommissioningSessionEstablishmentErrorMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);

mOnCommissioningSessionStoppedMethod = env->GetMethodID(chipAppServerDelegateClass, "onCommissioningSessionStopped", "()V");
VerifyOrReturnLogError(mOnCommissioningSessionStoppedMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);

mOnCommissioningWindowOpenedMethod = env->GetMethodID(chipAppServerDelegateClass, "onCommissioningWindowOpened", "()V");
VerifyOrReturnLogError(mOnCommissioningWindowOpenedMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);

mOnCommissioningWindowClosedMethod = env->GetMethodID(chipAppServerDelegateClass, "onCommissioningWindowClosed", "()V");
VerifyOrReturnLogError(mOnCommissioningWindowClosedMethod != nullptr, CHIP_JNI_ERROR_METHOD_NOT_FOUND);

return CHIP_NO_ERROR;
}
44 changes: 44 additions & 0 deletions src/app/server/java/ChipAppServerDelegate.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
*
* Copyright (c) 2023 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 <app/server/AppDelegate.h>
#include <jni.h>
#include <lib/core/CHIPError.h>

class ChipAppServerDelegate : public AppDelegate
{
public:
void OnCommissioningSessionEstablishmentStarted() override;
void OnCommissioningSessionStarted() override;
void OnCommissioningSessionEstablishmentError(CHIP_ERROR err) override;
void OnCommissioningSessionStopped() override;
void OnCommissioningWindowOpened() override;
void OnCommissioningWindowClosed() override;

CHIP_ERROR InitializeWithObjects(jobject appDelegateObject);

private:
jobject mChipAppServerDelegateObject = nullptr;
jmethodID mOnCommissioningSessionEstablishmentStartedMethod = nullptr;
jmethodID mOnCommissioningSessionStartedMethod = nullptr;
jmethodID mOnCommissioningSessionEstablishmentErrorMethod = nullptr;
jmethodID mOnCommissioningSessionStoppedMethod = nullptr;
jmethodID mOnCommissioningWindowOpenedMethod = nullptr;
jmethodID mOnCommissioningWindowClosedMethod = nullptr;
};
2 changes: 2 additions & 0 deletions src/app/server/java/src/chip/appserver/ChipAppServer.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,5 +36,7 @@ public ChipFabricProvider getFabricProvider() {

public native boolean startApp();

public native boolean startAppWithDelegate(ChipAppServerDelegate appDelegate);

public native boolean stopApp();
}
32 changes: 32 additions & 0 deletions src/app/server/java/src/chip/appserver/ChipAppServerDelegate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2023 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 interface ChipAppServerDelegate {
void onCommissioningSessionEstablishmentStarted();

void onCommissioningSessionStarted();

void onCommissioningSessionEstablishmentError(int errorCode);

void onCommissioningSessionStopped();

void onCommissioningWindowOpened();

void onCommissioningWindowClosed();
}

0 comments on commit 2b76339

Please sign in to comment.