Skip to content

Commit

Permalink
Added ChipDnssdPublishService and ChipDnssdRemoveServices imp on andr…
Browse files Browse the repository at this point in the history
…oid platform (#10971)

* added publish and remove for dnssd in android platform

* fix CHIPTest AS build error

* fix crash issue in dnssdimpl, DeleteRef error

* added java imp for dnssd

* fix restyled errors

* fix review issues:
1. publish and remove return void
2. remove -> removeServices
3. import for detail packages
4. naming consistent
5. remove DeleteLocalRef
  • Loading branch information
xylophone21 authored and pull[bot] committed Nov 25, 2021
1 parent 926ccfe commit c8527cc
Show file tree
Hide file tree
Showing 4 changed files with 159 additions and 9 deletions.
4 changes: 2 additions & 2 deletions src/android/CHIPTest/gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ kotlin.code.style=official

# Build SDK from source code and debug in Android Stduio. Must also set matterBuildSrcDir.
matterSdkSourceBuild=false
# Point to the SDK build dir without quotes (../../../../out/android-arm64-chip-test for
# Point to the SDK build dir without quotes (out/android-arm64-chip-test for
# example) to build SDK from source code and debug in Android Studio.
# Set to blank to use the SDK prebuilt by scripts/build/build_examples.py.
matterBuildSrcDir=../../../../out/android-arm64-chip-test
matterBuildSrcDir=out/android-arm64-chip-test

# Test libs to run
matterUTestLib=libPlatformTests.a
90 changes: 83 additions & 7 deletions src/platform/android/DnssdImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

#include "DnssdImpl.h"

#include <cstddef>
#include <jni.h>
#include <lib/support/CHIPJNIError.h>
#include <lib/support/JniReferences.h>
Expand All @@ -36,9 +37,11 @@ namespace Dnssd {
using namespace chip::Platform;

namespace {
jobject sResolverObject = nullptr;
jobject sMdnsCallbackObject = nullptr;
jmethodID sResolveMethod = nullptr;
jobject sResolverObject = nullptr;
jobject sMdnsCallbackObject = nullptr;
jmethodID sResolveMethod = nullptr;
jmethodID sPublishMethod = nullptr;
jmethodID sRemoveServicesMethod = nullptr;
} // namespace

// Implemention of functions declared in lib/dnssd/platform/Dnssd.h
Expand All @@ -59,17 +62,75 @@ CHIP_ERROR ChipDnssdShutdown()

CHIP_ERROR ChipDnssdRemoveServices()
{
return CHIP_ERROR_NOT_IMPLEMENTED;
VerifyOrReturnError(sResolverObject != nullptr && sRemoveServicesMethod != nullptr, CHIP_ERROR_INCORRECT_STATE);
JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();

env->CallVoidMethod(sResolverObject, sRemoveServicesMethod);

if (env->ExceptionCheck())
{
ChipLogError(Discovery, "Java exception in ChipDnssdRemoveServices");
env->ExceptionDescribe();
env->ExceptionClear();
return CHIP_JNI_ERROR_EXCEPTION_THROWN;
}

return CHIP_NO_ERROR;
}

CHIP_ERROR ChipDnssdPublishService(const DnssdService * service)
{
return CHIP_ERROR_NOT_IMPLEMENTED;
VerifyOrReturnError(service != nullptr, CHIP_ERROR_INVALID_ARGUMENT);
VerifyOrReturnError(sResolverObject != nullptr && sPublishMethod != nullptr, CHIP_ERROR_INCORRECT_STATE);

JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread();
UtfString jniName(env, service->mName);
UtfString jniHostName(env, service->mHostName);

std::string serviceType = service->mType;
serviceType += '.';
serviceType += (service->mProtocol == DnssdServiceProtocol::kDnssdProtocolUdp ? "_udp" : "_tcp");
UtfString jniServiceType(env, serviceType.c_str());

jclass stringClass = env->FindClass("java/lang/String");
jobjectArray keys = env->NewObjectArray(service->mTextEntrySize, stringClass, nullptr);

jclass arrayElemType = env->FindClass("[B");
jobjectArray datas = env->NewObjectArray(service->mTextEntrySize, arrayElemType, nullptr);

for (size_t i = 0; i < service->mTextEntrySize; i++)
{
UtfString jniKey(env, service->mTextEntries[i].mKey);
env->SetObjectArrayElement(keys, i, jniKey.jniValue());

ByteArray jniData(env, (const jbyte *) service->mTextEntries[i].mData, service->mTextEntries[i].mDataSize);
env->SetObjectArrayElement(datas, i, jniData.jniValue());
}

jobjectArray subTypes = env->NewObjectArray(service->mSubTypeSize, stringClass, nullptr);
for (size_t i = 0; i < service->mSubTypeSize; i++)
{
UtfString jniSubType(env, service->mSubTypes[i]);
env->SetObjectArrayElement(subTypes, i, jniSubType.jniValue());
}

env->CallVoidMethod(sResolverObject, sPublishMethod, jniName.jniValue(), jniHostName.jniValue(), jniServiceType.jniValue(),
service->mPort, keys, datas, subTypes);

if (env->ExceptionCheck())
{
ChipLogError(Discovery, "Java exception in ChipDnssdPublishService");
env->ExceptionDescribe();
env->ExceptionClear();
return CHIP_JNI_ERROR_EXCEPTION_THROWN;
}

return CHIP_NO_ERROR;
}

CHIP_ERROR ChipDnssdFinalizeServiceUpdate()
{
return CHIP_ERROR_NOT_IMPLEMENTED;
return CHIP_NO_ERROR;
}

CHIP_ERROR ChipDnssdBrowse(const char * type, DnssdServiceProtocol protocol, Inet::IPAddressType addressType,
Expand Down Expand Up @@ -120,12 +181,27 @@ void InitializeWithObjects(jobject resolverObject, jobject mdnsCallbackObject)

sResolveMethod =
env->GetMethodID(resolverClass, "resolve", "(Ljava/lang/String;Ljava/lang/String;JJLchip/platform/ChipMdnsCallback;)V");

if (sResolveMethod == nullptr)
{
ChipLogError(Discovery, "Failed to access Resolver 'resolve' method");
env->ExceptionClear();
}

sPublishMethod =
env->GetMethodID(resolverClass, "publish",
"(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;I[Ljava/lang/String;[[B[Ljava/lang/String;)V");
if (sPublishMethod == nullptr)
{
ChipLogError(Discovery, "Failed to access Resolver 'publish' method");
env->ExceptionClear();
}

sRemoveServicesMethod = env->GetMethodID(resolverClass, "removeServices", "()V");
if (sRemoveServicesMethod == nullptr)
{
ChipLogError(Discovery, "Failed to access Resolver 'removeServices' method");
env->ExceptionClear();
}
}

void HandleResolve(jstring instanceName, jstring serviceType, jstring address, jint port, jlong callbackHandle, jlong contextHandle)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import java.util.ArrayList;
import java.util.List;

public class NsdManagerServiceResolver implements ServiceResolver {
private static final String TAG = NsdManagerServiceResolver.class.getSimpleName();
private static final long RESOLVE_SERVICE_TIMEOUT = 30000;
private final NsdManager nsdManager;
private MulticastLock multicastLock;
private Handler mainThreadHandler;
private List<NsdManager.RegistrationListener> registrationListeners = new ArrayList<>();

public NsdManagerServiceResolver(Context context) {
this.nsdManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
Expand Down Expand Up @@ -112,4 +115,57 @@ public void onServiceResolved(NsdServiceInfo serviceInfo) {
});
mainThreadHandler.postDelayed(timeoutRunnable, RESOLVE_SERVICE_TIMEOUT);
}

@Override
public void publish(
String serviceName,
String hostName,
String type,
int port,
String[] textEntriesKeys,
byte[][] textEntriesDatas,
String[] subTypes) {
NsdServiceInfo serviceInfo = new NsdServiceInfo();
serviceInfo.setServiceName(serviceName);
serviceInfo.setServiceType(type);
serviceInfo.setPort(port);
Log.i(TAG, "publish serviceName=" + serviceName + " type=" + type + " port=" + port);

NsdManager.RegistrationListener registrationListener =
new NsdManager.RegistrationListener() {
@Override
public void onRegistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
Log.w(
TAG,
"service " + serviceInfo.getServiceName() + " onRegistrationFailed:" + errorCode);
}

@Override
public void onUnregistrationFailed(NsdServiceInfo serviceInfo, int errorCode) {
Log.w(
TAG,
"service " + serviceInfo.getServiceName() + " onUnregistrationFailed:" + errorCode);
}

@Override
public void onServiceRegistered(NsdServiceInfo serviceInfo) {
Log.i(TAG, "service " + serviceInfo.getServiceName() + " onServiceRegistered:");
}

@Override
public void onServiceUnregistered(NsdServiceInfo serviceInfo) {
Log.i(TAG, "service " + serviceInfo.getServiceName() + " onServiceRegistered:");
}
};
registrationListeners.add(registrationListener);

nsdManager.registerService(serviceInfo, NsdManager.PROTOCOL_DNS_SD, registrationListener);
}

@Override
public void removeServices() {
for (NsdManager.RegistrationListener l : registrationListeners) {
nsdManager.unregisterService(l);
}
}
}
18 changes: 18 additions & 0 deletions src/platform/android/java/chip/platform/ServiceResolver.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,22 @@ void resolve(
long callbackHandle,
long contextHandle,
ChipMdnsCallback chipMdnsCallback);

/**
* Publishes a service via DNS-SD.
*
* <p>Calling the function again with the same service name, type, protocol, interface and port
* but different text will update the text published.
*/
void publish(
String serviceName,
String hostName,
String type,
int port,
String[] textEntriesKeys,
byte[][] textEntriesDatas,
String[] subTypes);

/** Removes or marks all services being advertised for removal. */
void removeServices();
}

0 comments on commit c8527cc

Please sign in to comment.