Skip to content

Commit

Permalink
added DiagnosticDataProviderImpl for android (#15350)
Browse files Browse the repository at this point in the history
* added DiagnosticDataProviderImpl for android

* fix restyled-io and ci errors

* 1. added stackUnlock to fix java call jni error
2. using jbyteArray for jHardwareAddressObj

* fix chiptool build error and code style

* fix restyled-io and ci errors

* fix restyled-io and ci errors

* fix anInterface.offPremiseServicesReachableIPv4-6 error

* fix restyled-io and ci errors

* fix restyled-io and ci errors

* fix restyled-io and ci errors

* fix restyled-io and ci errors

* change offPremiseServicesReachableIPv4 and offPremiseServicesReachableIPv6 to Boolean

* fix restyled-io and ci errors
  • Loading branch information
xylophone21 authored and pull[bot] committed Feb 25, 2022
1 parent 1baac49 commit 4043848
Show file tree
Hide file tree
Showing 11 changed files with 360 additions and 7 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
/*
* Copyright (c) 2021-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 com.tcl.chip.chiptvserver.service;

import android.content.Context;
Expand All @@ -6,6 +23,7 @@
import chip.platform.AndroidBleManager;
import chip.platform.AndroidChipPlatform;
import chip.platform.ChipMdnsCallbackImpl;
import chip.platform.DiagnosticDataProviderImpl;
import chip.platform.NsdManagerServiceResolver;
import chip.platform.PreferencesConfigurationManager;
import chip.platform.PreferencesKeyValueStoreManager;
Expand Down Expand Up @@ -69,7 +87,8 @@ public void init(@NonNull Context context) {
new PreferencesKeyValueStoreManager(applicationContext),
new PreferencesConfigurationManager(applicationContext),
new NsdManagerServiceResolver(applicationContext),
new ChipMdnsCallbackImpl());
new ChipMdnsCallbackImpl(),
new DiagnosticDataProviderImpl(applicationContext));

chipAppServer = new ChipAppServer();
chipAppServer.startApp();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,6 @@ class MainActivity : AppCompatActivity() {
}.start()
}

AndroidChipPlatform(AndroidBleManager(), PreferencesKeyValueStoreManager(this), PreferencesConfigurationManager(this), NsdManagerServiceResolver(this), ChipMdnsCallbackImpl())
AndroidChipPlatform(AndroidBleManager(), PreferencesKeyValueStoreManager(this), PreferencesConfigurationManager(this), NsdManagerServiceResolver(this), ChipMdnsCallbackImpl(), DiagnosticDataProviderImpl(this))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import chip.devicecontroller.GetConnectedDeviceCallbackJni.GetConnectedDeviceCal
import chip.platform.AndroidBleManager
import chip.platform.AndroidChipPlatform
import chip.platform.ChipMdnsCallbackImpl
import chip.platform.DiagnosticDataProviderImpl
import chip.platform.NsdManagerServiceResolver
import chip.platform.PreferencesConfigurationManager
import chip.platform.PreferencesKeyValueStoreManager
Expand All @@ -50,7 +51,7 @@ object ChipClient {
if (!this::androidPlatform.isInitialized && context != null) {
//force ChipDeviceController load jni
ChipDeviceController.loadJni()
androidPlatform = AndroidChipPlatform(AndroidBleManager(), PreferencesKeyValueStoreManager(context), PreferencesConfigurationManager(context), NsdManagerServiceResolver(context), ChipMdnsCallbackImpl())
androidPlatform = AndroidChipPlatform(AndroidBleManager(), PreferencesKeyValueStoreManager(context), PreferencesConfigurationManager(context), NsdManagerServiceResolver(context), ChipMdnsCallbackImpl(), DiagnosticDataProviderImpl(context))
}
return androidPlatform
}
Expand Down
8 changes: 8 additions & 0 deletions src/platform/android/AndroidChipPlatform-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@

#include "AndroidChipPlatform-JNI.h"
#include "BLEManagerImpl.h"
#include "DiagnosticDataProviderImpl.h"
#include "DnssdImpl.h"

using namespace chip;
Expand Down Expand Up @@ -221,6 +222,13 @@ JNI_METHOD(void, setConfigurationManager)(JNIEnv * env, jclass self, jobject man
}
}

// for DiagnosticDataProviderManager
JNI_METHOD(void, setDiagnosticDataProviderManager)(JNIEnv * env, jclass self, jobject manager)
{
chip::DeviceLayer::StackLock lock;
chip::DeviceLayer::DiagnosticDataProviderImpl::GetDefaultInstance().InitializeWithObject(manager);
}

// for ServiceResolver
JNI_METHOD(void, nativeSetServiceResolver)(JNIEnv * env, jclass self, jobject resolver, jobject chipMdnsCallback)
{
Expand Down
8 changes: 7 additions & 1 deletion src/platform/android/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@ static_library("android") {
android_library("java") {
output_name = "AndroidPlatform.jar"

deps = [ ":android_sdk" ]
deps = [
":android_sdk",
"${chip_root}/third_party/android_deps:annotation",
]
data_deps = [ ":android" ]

sources = [
Expand All @@ -77,7 +80,10 @@ android_library("java") {
"java/chip/platform/ChipMdnsCallback.java",
"java/chip/platform/ChipMdnsCallbackImpl.java",
"java/chip/platform/ConfigurationManager.java",
"java/chip/platform/DiagnosticDataProvider.java",
"java/chip/platform/DiagnosticDataProviderImpl.java",
"java/chip/platform/KeyValueStoreManager.java",
"java/chip/platform/NetworkInterface.java",
"java/chip/platform/NsdManagerServiceResolver.java",
"java/chip/platform/PreferencesConfigurationManager.java",
"java/chip/platform/PreferencesKeyValueStoreManager.java",
Expand Down
159 changes: 158 additions & 1 deletion src/platform/android/DiagnosticDataProviderImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,21 @@
* for android platform.
*/

#include <cstddef>
#include <cstring>
#include <jni.h>
#include <platform/internal/CHIPDeviceLayerInternal.h>

#include "DiagnosticDataProviderImpl.h"
#include <lib/support/CHIPJNIError.h>
#include <lib/support/CHIPMem.h>
#include <lib/support/CHIPMemString.h>
#include <lib/support/JniTypeWrappers.h>
#include <lib/support/logging/CHIPLogging.h>
#include <platform/DiagnosticDataProvider.h>
#include <platform/android/DiagnosticDataProviderImpl.h>
#include <unistd.h>

using namespace ::chip::app::Clusters::GeneralDiagnostics;

namespace chip {
namespace DeviceLayer {
Expand All @@ -37,5 +46,153 @@ DiagnosticDataProviderImpl & DiagnosticDataProviderImpl::GetDefaultInstance()
return sInstance;
}

void DiagnosticDataProviderImpl::InitializeWithObject(jobject manager)
{
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
VerifyOrReturn(env != nullptr,
ChipLogError(DeviceLayer, "Failed to GetEnvForCurrentThread for DiagnosticDataProviderManagerImpl"));

mDiagnosticDataProviderManagerObject = env->NewGlobalRef(manager);
VerifyOrReturn(mDiagnosticDataProviderManagerObject != nullptr,
ChipLogError(DeviceLayer, "Failed to NewGlobalRef DiagnosticDataProviderManager"));

jclass DiagnosticDataProviderManagerClass = env->GetObjectClass(manager);
VerifyOrReturn(DiagnosticDataProviderManagerClass != nullptr,
ChipLogError(DeviceLayer, "Failed to get DiagnosticDataProviderManager Java class"));

mGetRebootCountMethod = env->GetMethodID(DiagnosticDataProviderManagerClass, "getRebootCount", "()I");
if (mGetRebootCountMethod == nullptr)
{
ChipLogError(DeviceLayer, "Failed to access DiagnosticDataProviderManager 'getRebootCount' method");
env->ExceptionClear();
}

mGetNifMethod =
env->GetMethodID(DiagnosticDataProviderManagerClass, "getNetworkInterfaces", "()[Lchip/platform/NetworkInterface;");
if (mGetNifMethod == nullptr)
{
ChipLogError(DeviceLayer, "Failed to access DiagnosticDataProviderManager 'getNetworkInterfaces' method");
env->ExceptionClear();
}
}

CHIP_ERROR DiagnosticDataProviderImpl::GetRebootCount(uint16_t & rebootCount)
{
chip::DeviceLayer::StackUnlock unlock;
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
VerifyOrReturnLogError(mDiagnosticDataProviderManagerObject != nullptr, CHIP_ERROR_INCORRECT_STATE);
VerifyOrReturnLogError(mGetRebootCountMethod != nullptr, CHIP_ERROR_INCORRECT_STATE);
VerifyOrReturnLogError(env != nullptr, CHIP_JNI_ERROR_NO_ENV);
ChipLogProgress(DeviceLayer, "Received GetRebootCount");

jint count = env->CallIntMethod(mDiagnosticDataProviderManagerObject, mGetRebootCountMethod);
VerifyOrReturnLogError(count < UINT16_MAX, CHIP_ERROR_INVALID_INTEGER_VALUE);
rebootCount = static_cast<uint16_t>(count);

return CHIP_NO_ERROR;
}

CHIP_ERROR DiagnosticDataProviderImpl::GetNetworkInterfaces(NetworkInterface ** netifpp)
{
chip::DeviceLayer::StackUnlock unlock;
CHIP_ERROR err = CHIP_NO_ERROR;
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
VerifyOrExit(mDiagnosticDataProviderManagerObject != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
VerifyOrExit(mGetNifMethod != nullptr, err = CHIP_ERROR_INCORRECT_STATE);
VerifyOrExit(env != nullptr, err = CHIP_JNI_ERROR_NO_ENV);
{
ChipLogProgress(DeviceLayer, "Received GetNetworkInterfaces");
jobjectArray nifList = (jobjectArray) env->CallObjectMethod(mDiagnosticDataProviderManagerObject, mGetNifMethod);
if (env->ExceptionCheck())
{
ChipLogError(DeviceLayer, "Java exception in DiagnosticDataProviderImpl::GetNetworkInterfaces");
env->ExceptionDescribe();
env->ExceptionClear();
return CHIP_ERROR_INCORRECT_STATE;
}
jint length = env->GetArrayLength(nifList);

NetworkInterface * head = nullptr;
for (jint i = 0; i < length; i++)
{
NetworkInterface * ifp = new NetworkInterface();

jobject nifObject = env->GetObjectArrayElement(nifList, i);
jclass nifClass = env->GetObjectClass(nifObject);

jfieldID getNameField = env->GetFieldID(nifClass, "name", "Ljava/lang/String;");
jstring jname = static_cast<jstring>(env->GetObjectField(nifObject, getNameField));
if (jname != nullptr)
{
JniUtfString name(env, jname);
Platform::CopyString(ifp->Name, name.c_str());
ifp->Name[Inet::InterfaceId::kMaxIfNameLength - 1] = '\0';
ifp->name = CharSpan(ifp->Name, strlen(ifp->Name));
}

jfieldID isOperationalField = env->GetFieldID(nifClass, "isOperational", "Z");
ifp->isOperational = static_cast<bool>(env->GetBooleanField(nifObject, isOperationalField));

jfieldID getOpsrIPV4Field = env->GetFieldID(nifClass, "offPremiseServicesReachableIPv4", "Ljava/lang/Boolean;");
jobject opsrIPV4Obj = env->GetObjectField(nifObject, getOpsrIPV4Field);
if (opsrIPV4Obj == nullptr)
{
ifp->offPremiseServicesReachableIPv4.SetNull();
}
else
{
jboolean opsrIPV4 = JniReferences::GetInstance().BooleanToPrimitive(opsrIPV4Obj);
ifp->offPremiseServicesReachableIPv4.SetNonNull(static_cast<bool>(opsrIPV4));
}

jfieldID getOpsrIPV6Field = env->GetFieldID(nifClass, "offPremiseServicesReachableIPv6", "Ljava/lang/Boolean;");
jobject opsrIPV6Obj = env->GetObjectField(nifObject, getOpsrIPV6Field);
if (opsrIPV6Obj == nullptr)
{
ifp->offPremiseServicesReachableIPv6.SetNull();
}
else
{
jboolean opsrIPV6 = JniReferences::GetInstance().BooleanToPrimitive(opsrIPV6Obj);
ifp->offPremiseServicesReachableIPv6.SetNonNull(static_cast<bool>(opsrIPV6));
}

jfieldID gethardwareAddressField = env->GetFieldID(nifClass, "hardwareAddress", "[B");
jbyteArray jHardwareAddressObj = static_cast<jbyteArray>(env->GetObjectField(nifObject, gethardwareAddressField));
if (jHardwareAddressObj != nullptr)
{
size_t len = env->GetArrayLength(jHardwareAddressObj);
len = (len > kMaxHardwareAddrSize) ? kMaxHardwareAddrSize : len;
env->GetByteArrayRegion(jHardwareAddressObj, 0, len, reinterpret_cast<jbyte *>(ifp->MacAddress));
ifp->hardwareAddress = ByteSpan(ifp->MacAddress, 6);
}

jfieldID getTypeField = env->GetFieldID(nifClass, "type", "I");
ifp->type = static_cast<InterfaceType>(env->GetIntField(nifObject, getTypeField));

ifp->Next = head;
head = ifp;
}
*netifpp = head;
}

exit:
if (err != CHIP_NO_ERROR)
{
ChipLogError(Zcl, "ChannelManager::getChannelList status error: %s", err.AsString());
}
return err;
}

void DiagnosticDataProviderImpl::ReleaseNetworkInterfaces(NetworkInterface * netifp)
{
while (netifp)
{
NetworkInterface * del = netifp;
netifp = netifp->Next;
delete del;
}
}

} // namespace DeviceLayer
} // namespace chip
17 changes: 17 additions & 0 deletions src/platform/android/DiagnosticDataProviderImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,15 @@

#pragma once

#include <jni.h>
#include <platform/DiagnosticDataProvider.h>

namespace {
constexpr int offPremiseServicesReachableUnknown = 0;
constexpr int offPremiseServicesReachableYes = 1;
constexpr int offPremiseServicesReachableNo = 2;
} // namespace

namespace chip {
namespace DeviceLayer {

Expand All @@ -32,8 +39,18 @@ namespace DeviceLayer {
*/
class DiagnosticDataProviderImpl : public DiagnosticDataProvider
{
public:
void InitializeWithObject(jobject managerObject);

public:
static DiagnosticDataProviderImpl & GetDefaultInstance();
CHIP_ERROR GetRebootCount(uint16_t & rebootCount) override;
CHIP_ERROR GetNetworkInterfaces(NetworkInterface ** netifpp) override;
void ReleaseNetworkInterfaces(NetworkInterface * netifp) override;

jobject mDiagnosticDataProviderManagerObject = nullptr;
jmethodID mGetRebootCountMethod = nullptr;
jmethodID mGetNifMethod = nullptr;
};

} // namespace DeviceLayer
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2021 Project CHIP Authors
* Copyright (c) 2021-2022 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
Expand All @@ -25,14 +25,16 @@ public AndroidChipPlatform(
KeyValueStoreManager kvm,
ConfigurationManager cfg,
ServiceResolver resolver,
ChipMdnsCallback chipMdnsCallback) {
ChipMdnsCallback chipMdnsCallback,
DiagnosticDataProvider dataProvider) {
// Order is important here: initChipStack() initializes the BLEManagerImpl, which depends on the
// BLEManager being set. setConfigurationManager() depends on the CHIP stack being initialized.
setBLEManager(ble);
initChipStack();
setKeyValueStoreManager(kvm);
setConfigurationManager(cfg);
setServiceResolver(resolver, chipMdnsCallback);
setDiagnosticDataProviderManager(dataProvider);
}

// for BLEManager
Expand Down Expand Up @@ -87,4 +89,6 @@ private void setServiceResolver(ServiceResolver resolver, ChipMdnsCallback chipM

private native void nativeSetServiceResolver(
ServiceResolver resolver, ChipMdnsCallback chipMdnsCallback);

private native void setDiagnosticDataProviderManager(DiagnosticDataProvider dataProviderCallback);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* 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.platform;

public interface DiagnosticDataProvider {
int getRebootCount();

NetworkInterface[] getNetworkInterfaces();
}
Loading

0 comments on commit 4043848

Please sign in to comment.