Skip to content

Commit

Permalink
Android updates
Browse files Browse the repository at this point in the history
  • Loading branch information
sharadb-amazon committed Sep 20, 2023
1 parent d115d93 commit a169f02
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 67 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;

public class TvCastingApp {
Expand All @@ -52,6 +53,7 @@ public class TvCastingApp {
private WifiManager.MulticastLock multicastLock;
private NsdManager nsdManager;
private NsdDiscoveryListener nsdDiscoveryListener;
private ScheduledFuture<?> reportSleepingCommissionersFuture;

private TvCastingApp() {}

Expand Down Expand Up @@ -154,21 +156,24 @@ public void discoverVideoPlayerCommissioners(
DISCOVERY_TARGET_SERVICE_TYPE, NsdManager.PROTOCOL_DNS_SD, nsdDiscoveryListener);
Log.d(TAG, "TvCastingApp.discoverVideoPlayerCommissioners started");

Executors.newScheduledThreadPool(1)
.schedule(
() -> {
Log.d(
TAG,
"Scheduling reportSleepingCommissioners with commissioner count "
+ (preCommissionedVideoPlayers != null
? preCommissionedVideoPlayers.size()
: 0));
reportSleepingCommissioners(preCommissionedVideoPlayers, discoverySuccessCallback);
},
5000,
TimeUnit.MILLISECONDS);
this.reportSleepingCommissionersFuture =
Executors.newScheduledThreadPool(1)
.schedule(
() -> {
Log.d(
TAG,
"Scheduling reportSleepingCommissioners with commissioner count "
+ (preCommissionedVideoPlayers != null
? preCommissionedVideoPlayers.size()
: 0));
reportSleepingCommissioners(
preCommissionedVideoPlayers, discoverySuccessCallback);
},
5000,
TimeUnit.MILLISECONDS);

this.discoveryStarted = true;
reportSleepingCommissionersFuture.cancel(true);
}
}

Expand Down Expand Up @@ -201,7 +206,8 @@ public void stopVideoPlayerDiscovery() {
if (this.discoveryStarted
&& nsdManager != null
&& multicastLock != null
&& nsdDiscoveryListener != null) {
&& nsdDiscoveryListener != null
&& reportSleepingCommissionersFuture != null) {
Log.d(TAG, "TvCastingApp stopping Video Player commissioner discovery");
try {
nsdManager.stopServiceDiscovery(nsdDiscoveryListener);
Expand All @@ -215,6 +221,8 @@ public void stopVideoPlayerDiscovery() {
if (multicastLock.isHeld()) {
multicastLock.release();
}

reportSleepingCommissionersFuture.cancel(false);
this.discoveryStarted = false;
}
}
Expand All @@ -239,61 +247,45 @@ public boolean verifyOrEstablishConnection(
SuccessCallback<VideoPlayer> onConnectionSuccess,
FailureCallback onConnectionFailure,
SuccessCallback<ContentApp> onNewOrUpdatedEndpointCallback) {
// check if the targetVideoPlayer is asleep and if so, send WakeOnLAN packet to it
if (targetVideoPlayer.isAsleep()) {
Log.d(TAG, "TvCastingApp.verifyOrEstablishConnection called");
if (!targetVideoPlayer.isAsleep()) {
// if the player is NOT asleep, establish connection right away
return _verifyOrEstablishConnection(
targetVideoPlayer,
onConnectionSuccess,
onConnectionFailure,
onNewOrUpdatedEndpointCallback);
} else {
boolean status = false;
// targetVideoPlayer is asleep. Send WakeOnLAN packet to it
if (_sendWakeOnLAN(targetVideoPlayer)) {
// check if it woke up by discovering it
discoverVideoPlayerCommissioners(
new SuccessCallback<DiscoveredNodeData>() {
@Override
public void handle(DiscoveredNodeData response) {
Log.d(
TAG,
"Video player discovered after WakeOnLAN with hostname "
+ response.getHostName());
if (targetVideoPlayer.getHostName().equals(response.getHostName())) {
targetVideoPlayer.setAsleep(false); // not asleep anymore
status = true;
// wait for player to turn on, then establish connection
Log.d(TAG, "Scheduling delayed call to _verifyOrEstablishConnection after sending WoL");
Executors.newScheduledThreadPool(1)
.schedule(
() -> {
boolean callStatus =
_verifyOrEstablishConnection(
targetVideoPlayer,
onConnectionSuccess,
new SuccessCallback<VideoPlayer>() {
@Override
public void handle(VideoPlayer response) {
response.setAsleep(false);
onConnectionSuccess.handle(response);
}
},
onConnectionFailure,
onNewOrUpdatedEndpointCallback);
if (callStatus == false) {
Log.e(
TAG,
"_verifyOrEstablishConnection failed after waking up and discovering targetVideoPlayer");
Log.e(TAG, "_verifyOrEstablishConnection failed after attempting to WoL");
onConnectionFailure.handle(new MatterError(0x03, "CHIP_ERROR_INCORRECT_STATE"));
}
}
}
},
new FailureCallback() {
@Override
public void handle(MatterError err) {
Log.e(TAG, "Failure while discovering targetVideoPlayer after waking it up " + err);
}
});

// stop looking for the video player after some time and fail fast
Executors.newScheduledThreadPool(1)
.schedule(
() -> {
Log.d(TAG, "Scheduling stopVideoPlayerDiscovery after sending WoL");
stopVideoPlayerDiscovery();
},
10000,
TimeUnit.MILLISECONDS);
status = true;
}
return status;
} else {
return _verifyOrEstablishConnection(
targetVideoPlayer,
onConnectionSuccess,
onConnectionFailure,
onNewOrUpdatedEndpointCallback);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ CHIP_ERROR convertJVideoPlayerToTargetVideoPlayerInfo(jobject videoPlayer, Targe
const char * instanceName = env->GetStringUTFChars(jInstanceName, 0);

jfieldID jLastDiscoveredMs = env->GetFieldID(jVideoPlayerClass, "lastDiscoveredMs", "J");
long lastDiscoveredMs = static_cast<uint16_t>(env->GetIntField(videoPlayer, jLastDiscoveredMs));
long lastDiscoveredMs = static_cast<long>(env->GetLongField(videoPlayer, jLastDiscoveredMs));

jfieldID getMACAddressField = env->GetFieldID(jVideoPlayerClass, "MACAddress", "Ljava/lang/String;");
jstring jMACAddress = static_cast<jstring>(env->GetObjectField(videoPlayer, getMACAddressField));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -243,13 +243,13 @@ JNI_METHOD(jobject, readCachedVideoPlayers)(JNIEnv * env, jobject)
return jVideoPlayerList;
}

JNI_METHOD(jboolean, _verifyOrEstablishConnection)
JNI_METHOD(jboolean, _1verifyOrEstablishConnection)
(JNIEnv * env, jobject, jobject videoPlayer, jobject jOnConnectionSuccessHandler, jobject jOnConnectionFailureHandler,
jobject jOnNewOrUpdatedEndpointHandler)
{
chip::DeviceLayer::StackLock lock;

ChipLogProgress(AppServer, "JNI_METHOD verifyOrEstablishConnection called");
ChipLogProgress(AppServer, "JNI_METHOD _1verifyOrEstablishConnection called");

TargetVideoPlayerInfo targetVideoPlayerInfo;
CHIP_ERROR err = convertJVideoPlayerToTargetVideoPlayerInfo(videoPlayer, targetVideoPlayerInfo);
Expand All @@ -276,18 +276,18 @@ JNI_METHOD(jboolean, _verifyOrEstablishConnection)
[](CHIP_ERROR err) { TvCastingAppJNIMgr().getOnConnectionFailureHandler(true).Handle(err); },
[](TargetEndpointInfo * endpoint) { TvCastingAppJNIMgr().getOnNewOrUpdatedEndpointHandler(true).Handle(endpoint); });
VerifyOrExit(CHIP_NO_ERROR == err,
ChipLogError(AppServer, "CastingServer::verifyOrEstablishConnection failed: %" CHIP_ERROR_FORMAT, err.Format()));
ChipLogError(AppServer, "CastingServer::_1verifyOrEstablishConnection failed: %" CHIP_ERROR_FORMAT, err.Format()));

exit:
return (err == CHIP_NO_ERROR);
}

JNI_METHOD(jboolean, _sendWakeOnLAN)
JNI_METHOD(jboolean, _1sendWakeOnLAN)
(JNIEnv * env, jobject, jobject videoPlayer)
{
chip::DeviceLayer::StackLock lock;

ChipLogProgress(AppServer, "JNI_METHOD _sendWakeOnLAN called");
ChipLogProgress(AppServer, "JNI_METHOD _1sendWakeOnLAN called");

TargetVideoPlayerInfo targetVideoPlayerInfo;
CHIP_ERROR err = convertJVideoPlayerToTargetVideoPlayerInfo(videoPlayer, targetVideoPlayerInfo);
Expand Down
14 changes: 7 additions & 7 deletions examples/tv-casting-app/tv-casting-common/src/CastingServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -362,10 +362,10 @@ CastingServer::GetDiscoveredCommissioner(int index, chip::Optional<TargetVideoPl

CHIP_ERROR CastingServer::SendWakeOnLAN(TargetVideoPlayerInfo & targetVideoPlayerInfo)
{
VerifyOrReturnError(targetVideoPlayerInfo.getMACAddress() != nullptr && targetVideoPlayerInfo.getMACAddress()->size() > 0,
CHIP_ERROR_INVALID_ARGUMENT);
chip::CharSpan MACAddress = *(targetVideoPlayerInfo.getMACAddress());
ChipLogProgress(AppServer, "SendWakeOnLAN called with MACAddress %.*s", 2 * kMACLength, MACAddress.data());
chip::CharSpan * MACAddress = targetVideoPlayerInfo.GetMACAddress();
VerifyOrReturnError(MACAddress != nullptr && MACAddress->size() > 0, CHIP_ERROR_INVALID_ARGUMENT);
const int kMACLength = chip::DeviceLayer::ConfigurationManager::kPrimaryMACAddressLength;
ChipLogProgress(AppServer, "SendWakeOnLAN called with MACAddress %.*s", 2 * kMACLength, MACAddress->data());

// Create a socket
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
Expand All @@ -385,13 +385,12 @@ CHIP_ERROR CastingServer::SendWakeOnLAN(TargetVideoPlayerInfo & targetVideoPlaye
}

// Convert MAC Address to bytes
const int kMACLength = chip::DeviceLayer::ConfigurationManager::kPrimaryMACAddressLength;
uint8_t MACBytes[kMACLength];
for (int i = 0; i < 2 * kMACLength; i += 2)
{
char byteString[3];
byteString[0] = MACAddress.data()[i];
byteString[1] = MACAddress.data()[i + 1];
byteString[0] = MACAddress->data()[i];
byteString[1] = MACAddress->data()[i + 1];
byteString[2] = '\0';
MACBytes[i / 2] = static_cast<uint8_t>(std::strtol(byteString, nullptr, 16));
}
Expand All @@ -418,6 +417,7 @@ CHIP_ERROR CastingServer::SendWakeOnLAN(TargetVideoPlayerInfo & targetVideoPlaye
ChipLogError(AppServer, "sendto(): Could not send WoL magic packet");
return CHIP_ERROR_INCORRECT_STATE;
}
ChipLogProgress(AppServer, "Broadcasted WoL magic packet with MACAddress %.*s", 2 * kMACLength, MACAddress->data());

close(sockfd);
return CHIP_NO_ERROR;
Expand Down

0 comments on commit a169f02

Please sign in to comment.