diff --git a/examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/ConnectionExampleFragment.java b/examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/ConnectionExampleFragment.java
index b61b63f3e0785e..38616434cc6a03 100644
--- a/examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/ConnectionExampleFragment.java
+++ b/examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/ConnectionExampleFragment.java
@@ -31,6 +31,8 @@
import androidx.fragment.app.Fragment;
import com.R;
import com.matter.casting.core.CastingPlayer;
+import com.matter.casting.core.CastingPlayerDiscovery;
+import com.matter.casting.core.MatterCastingPlayerDiscovery;
import com.matter.casting.support.CommissionerDeclaration;
import com.matter.casting.support.ConnectionCallbacks;
import com.matter.casting.support.IdentificationDeclarationOptions;
@@ -56,6 +58,10 @@ public class ConnectionExampleFragment extends Fragment {
private TextView connectionFragmentStatusTextView;
private Button connectionFragmentNextButton;
+ // Get a singleton instance of the MatterCastingPlayerDiscovery. Which can be used to call stopDiscovery() during connection.
+ static final CastingPlayerDiscovery matterCastingPlayerDiscovery =
+ MatterCastingPlayerDiscovery.getInstance();
+
public ConnectionExampleFragment(
CastingPlayer targetCastingPlayer, boolean useCommissionerGeneratedPasscode) {
Log.i(
@@ -123,6 +129,13 @@ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
callback.handleConnectionComplete(targetCastingPlayer, useCommissionerGeneratedPasscode);
});
+ Button stopDiscoveryButton = getView().findViewById(R.id.stopDiscoveryButton);
+ stopDiscoveryButton.setOnClickListener(
+ v -> {
+ Log.i(TAG, "onViewCreated() stopDiscoveryButton button clicked. Calling stopDiscovery()");
+ stopDiscovery();
+ });
+
Executors.newSingleThreadExecutor()
.submit(
() -> {
@@ -160,13 +173,17 @@ public void handle(Void v) {
Log.i(
TAG,
"Successfully connected to CastingPlayer with deviceId: "
- + targetCastingPlayer.getDeviceId());
+ + targetCastingPlayer.getDeviceId()
+ + ", useCommissionerGeneratedPasscode: "
+ + useCommissionerGeneratedPasscode);
getActivity()
.runOnUiThread(
() -> {
connectionFragmentStatusTextView.setText(
"Successfully connected to Casting Player with device name: "
+ targetCastingPlayer.getDeviceName()
+ + "\n\nUsed CastingPlayer Passcode: "
+ + useCommissionerGeneratedPasscode
+ "\n\n");
connectionFragmentNextButton.setEnabled(true);
});
@@ -351,6 +368,19 @@ public void onClick(DialogInterface dialog, int which) {
.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT);
}
+ private void stopDiscovery() {
+ Log.i(TAG, "ConnectionExampleFragment stopDiscovery() called, calling MatterCastingPlayerDiscovery.stopDiscovery()");
+
+ MatterError err = matterCastingPlayerDiscovery.stopDiscovery();
+ if (err.hasError()) {
+ Log.e(
+ TAG,
+ "ConnectionExampleFragment stopDiscovery() MatterCastingPlayerDiscovery.stopDiscovery() called, err Stop: " + err);
+ } else {
+ Log.d(TAG, "ConnectionExampleFragment stopDiscovery() MatterCastingPlayerDiscovery.stopDiscovery() success");
+ }
+ }
+
/** Interface for notifying the host. */
public interface Callback {
/** Notifies listener to trigger transition on completion of connection */
diff --git a/examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/DiscoveryExampleFragment.java b/examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/DiscoveryExampleFragment.java
index 3dca2320b8924c..3bb791375f8bfe 100644
--- a/examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/DiscoveryExampleFragment.java
+++ b/examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/DiscoveryExampleFragment.java
@@ -67,7 +67,7 @@ public class DiscoveryExampleFragment extends Fragment {
public void onAdded(CastingPlayer castingPlayer) {
Log.i(
TAG,
- "onAdded() Discovered CastingPlayer deviceId: " + castingPlayer.getDeviceId());
+ "DiscoveryExampleFragment onAdded() Discovered CastingPlayer deviceId: " + castingPlayer.getDeviceId());
// Display CastingPlayer info on the screen
new Handler(Looper.getMainLooper())
.post(
@@ -80,7 +80,7 @@ public void onAdded(CastingPlayer castingPlayer) {
public void onChanged(CastingPlayer castingPlayer) {
Log.i(
TAG,
- "onChanged() Discovered changes to CastingPlayer with deviceId: "
+ "DiscoveryExampleFragment onChanged() Discovered changes to CastingPlayer with deviceId: "
+ castingPlayer.getDeviceId());
// Update the CastingPlayer on the screen
new Handler(Looper.getMainLooper())
@@ -107,7 +107,7 @@ public void onChanged(CastingPlayer castingPlayer) {
public void onRemoved(CastingPlayer castingPlayer) {
Log.i(
TAG,
- "onRemoved() Removed CastingPlayer with deviceId: "
+ "DiscoveryExampleFragment onRemoved() Removed CastingPlayer with deviceId: "
+ castingPlayer.getDeviceId());
// Remove CastingPlayer from the screen
new Handler(Looper.getMainLooper())
@@ -215,7 +215,9 @@ public void onResume() {
@Override
public void onPause() {
super.onPause();
- Log.i(TAG, "onPause() called");
+ Log.i(TAG, "DiscoveryExampleFragment onPause() called, calling stopDiscovery()");
+ // Stop discovery when leaving the fragment, for example, while displaying the ConnectionExampleFragment.
+ stopDiscovery();
}
/** Interface for notifying the host. */
@@ -261,7 +263,7 @@ private boolean startDiscovery() {
}
private void stopDiscovery() {
- Log.i(TAG, "stopDiscovery() called");
+ Log.i(TAG, "DiscoveryExampleFragment stopDiscovery() called");
matterDiscoveryErrorMessageTextView.setText(
getString(R.string.matter_discovery_error_message_initial));
diff --git a/examples/tv-casting-app/android/App/app/src/main/res/layout/custom_passcode_dialog.xml b/examples/tv-casting-app/android/App/app/src/main/res/layout/custom_passcode_dialog.xml
index 1b868e06b71f29..c91fa4ad404089 100644
--- a/examples/tv-casting-app/android/App/app/src/main/res/layout/custom_passcode_dialog.xml
+++ b/examples/tv-casting-app/android/App/app/src/main/res/layout/custom_passcode_dialog.xml
@@ -1,5 +1,6 @@
@@ -11,7 +12,6 @@
android:textStyle="bold"
android:textSize="18sp"
android:padding="16dp"
- android:textColor="@android:color/white"
android:gravity="center"
android:text="@string/matter_connection_input_dialog_title" />
@@ -24,7 +24,6 @@
android:paddingEnd="16dp"
android:paddingTop="8dp"
android:paddingBottom="8dp"
- android:textColor="@android:color/white"
android:text="@string/matter_connection_input_dialog_instructions" />
-
-
-
+ android:orientation="vertical"
+ tools:layout_editor_absoluteX="1dp"
+ tools:layout_editor_absoluteY="1dp"
+ android:padding="10sp">
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp
index cff903a1a1316b..4bddbd87422b81 100644
--- a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp
+++ b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.cpp
@@ -17,7 +17,7 @@
*/
#include "CastingPlayer.h"
-#include "Endpoint.h"
+#include "CastingPlayerDiscovery.h"
#include "support/CastingStore.h"
@@ -27,13 +27,14 @@ namespace matter {
namespace casting {
namespace core {
-CastingPlayer * CastingPlayer::mTargetCastingPlayer = nullptr;
+memory::Weak CastingPlayer::mTargetCastingPlayer;
void CastingPlayer::VerifyOrEstablishConnection(ConnectionCallbacks connectionCallbacks, uint16_t commissioningWindowTimeoutSec,
IdentificationDeclarationOptions idOptions)
{
ChipLogProgress(AppServer, "CastingPlayer::VerifyOrEstablishConnection() called");
+ CastingPlayerDiscovery * castingPlayerDiscovery = CastingPlayerDiscovery::GetInstance();
std::vector::iterator it;
std::vector cachedCastingPlayers = support::CastingStore::GetInstance()->ReadAll();
@@ -53,8 +54,9 @@ void CastingPlayer::VerifyOrEstablishConnection(ConnectionCallbacks connectionCa
mConnectionState = CASTING_PLAYER_CONNECTING;
mOnCompleted = connectionCallbacks.mOnConnectionComplete;
mCommissioningWindowTimeoutSec = commissioningWindowTimeoutSec;
- mTargetCastingPlayer = this;
+ mTargetCastingPlayer = weak_from_this();
mIdOptions = idOptions;
+ castingPlayerDiscovery->ClearDisconnectedCastingPlayersInternal();
// Register the handler for Commissioner's CommissionerDeclaration messages. The CommissionerDeclaration messages provide
// information indicating the Commissioner's pre-commissioning state.
@@ -120,7 +122,7 @@ void CastingPlayer::VerifyOrEstablishConnection(ConnectionCallbacks connectionCa
nullptr,
[](void * context, chip::Messaging::ExchangeManager & exchangeMgr, const chip::SessionHandle & sessionHandle) {
ChipLogProgress(AppServer,
- "CastingPlayer::VerifyOrEstablishConnection() Connection to CastingPlayer successful");
+ "CastingPlayer::VerifyOrEstablishConnection() FindOrEstablishSession Connection to CastingPlayer successful");
CastingPlayer::GetTargetCastingPlayer()->mConnectionState = CASTING_PLAYER_CONNECTED;
// this async call will Load all the endpoints with their respective attributes into the TargetCastingPlayer
@@ -129,7 +131,7 @@ void CastingPlayer::VerifyOrEstablishConnection(ConnectionCallbacks connectionCa
support::EndpointListLoader::GetInstance()->Load();
},
[](void * context, const chip::ScopedNodeId & peerId, CHIP_ERROR error) {
- ChipLogError(AppServer, "CastingPlayer::VerifyOrEstablishConnection() Connection to CastingPlayer failed");
+ ChipLogError(AppServer, "CastingPlayer::VerifyOrEstablishConnection() FindOrEstablishSession Connection to CastingPlayer failed");
CastingPlayer::GetTargetCastingPlayer()->mConnectionState = CASTING_PLAYER_NOT_CONNECTED;
CHIP_ERROR e = support::CastingStore::GetInstance()->Delete(*CastingPlayer::GetTargetCastingPlayer());
if (e != CHIP_NO_ERROR)
@@ -139,7 +141,7 @@ void CastingPlayer::VerifyOrEstablishConnection(ConnectionCallbacks connectionCa
VerifyOrReturn(CastingPlayer::GetTargetCastingPlayer()->mOnCompleted);
CastingPlayer::GetTargetCastingPlayer()->mOnCompleted(error, nullptr);
- mTargetCastingPlayer = nullptr;
+ mTargetCastingPlayer.reset();
});
return; // FindOrEstablishSession called. Return early.
}
@@ -195,8 +197,8 @@ CHIP_ERROR CastingPlayer::ContinueConnecting()
"CastingPlayer::ContinueConnecting() mIdOptions.mCommissionerPasscode == false, ContinueConnecting() should "
"only be called when the CastingPlayer/Commissioner-Generated passcode commissioning flow is in progress."););
- CHIP_ERROR err = CHIP_NO_ERROR;
- mTargetCastingPlayer = this;
+ CHIP_ERROR err = CHIP_NO_ERROR;
+ mTargetCastingPlayer = weak_from_this();
ChipLogProgress(AppServer, "CastingPlayer::ContinueConnecting() calling OpenBasicCommissioningWindow()");
SuccessOrExit(err = chip::Server::GetInstance().GetCommissioningWindowManager().OpenBasicCommissioningWindow(
@@ -235,7 +237,8 @@ CHIP_ERROR CastingPlayer::StopConnecting()
mIdOptions.mCancelPasscode = true;
mConnectionState = CASTING_PLAYER_NOT_CONNECTED;
mCommissioningWindowTimeoutSec = kCommissioningWindowTimeoutSec;
- mTargetCastingPlayer = nullptr;
+ mTargetCastingPlayer.reset();
+ CastingPlayerDiscovery::GetInstance()->ClearCastingPlayersInternal();
// If a CastingPlayer::ContinueConnecting() error occurs, StopConnecting() can be called while sUdcInProgress == true.
// sUdcInProgress should be set to false before sending the CancelPasscode IdentificationDeclaration message to the
@@ -273,18 +276,21 @@ void CastingPlayer::resetState(CHIP_ERROR err)
support::ChipDeviceEventHandler::SetUdcStatus(false);
mConnectionState = CASTING_PLAYER_NOT_CONNECTED;
mCommissioningWindowTimeoutSec = kCommissioningWindowTimeoutSec;
- mTargetCastingPlayer = nullptr;
+ mTargetCastingPlayer.reset();
if (mOnCompleted)
{
mOnCompleted(err, nullptr);
mOnCompleted = nullptr;
}
+ CastingPlayerDiscovery::GetInstance()->ClearCastingPlayersInternal();
}
void CastingPlayer::Disconnect()
{
+ ChipLogProgress(AppServer, "CastingPlayer::Disconnect()");
mConnectionState = CASTING_PLAYER_NOT_CONNECTED;
- mTargetCastingPlayer = nullptr;
+ mTargetCastingPlayer.reset();
+ CastingPlayerDiscovery::GetInstance()->ClearCastingPlayersInternal();
}
void CastingPlayer::RegisterEndpoint(const memory::Strong endpoint)
@@ -320,6 +326,7 @@ CHIP_ERROR CastingPlayer::SendUserDirectedCommissioningRequest()
ReturnErrorOnFailure(chip::Server::GetInstance().SendUserDirectedCommissioningRequest(
chip::Transport::PeerAddress::UDP(*ipAddressToUse, mAttributes.port, mAttributes.interfaceId), id));
+ ChipLogProgress(AppServer, "CastingPlayer::SendUserDirectedCommissioningRequest() complete");
return CHIP_NO_ERROR;
}
@@ -478,23 +485,26 @@ ConnectionContext::ConnectionContext(void * clientContext, core::CastingPlayer *
mOnConnectedCallback = new chip::Callback::Callback(
[](void * context, chip::Messaging::ExchangeManager & exchangeMgr, const chip::SessionHandle & sessionHandle) {
- ChipLogProgress(AppServer, "Device Connection success callback called");
+ ChipLogProgress(AppServer, "CastingPlayer::ConnectionContext() Device Connection success callback called");
ConnectionContext * connectionContext = static_cast(context);
VerifyOrReturn(connectionContext != nullptr && connectionContext->mTargetCastingPlayer != nullptr,
- ChipLogError(AppServer, "Invalid ConnectionContext received in DeviceConnection success callback"));
+ ChipLogError(AppServer, "CastingPlayer::ConnectionContext() Invalid ConnectionContext received in DeviceConnection success callback"));
+ ChipLogProgress(AppServer, "CastingPlayer::ConnectionContext() calling mConnectionState = core::CASTING_PLAYER_CONNECTED");
connectionContext->mTargetCastingPlayer->mConnectionState = core::CASTING_PLAYER_CONNECTED;
+ ChipLogProgress(AppServer, "CastingPlayer::ConnectionContext() calling mOnDeviceConnectedFn");
connectionContext->mOnDeviceConnectedFn(connectionContext->mClientContext, exchangeMgr, sessionHandle);
+ ChipLogProgress(AppServer, "CastingPlayer::ConnectionContext() calling delete connectionContext");
delete connectionContext;
},
this);
mOnConnectionFailureCallback = new chip::Callback::Callback(
[](void * context, const chip::ScopedNodeId & peerId, CHIP_ERROR error) {
- ChipLogError(AppServer, "Device Connection failure callback called with %" CHIP_ERROR_FORMAT, error.Format());
+ ChipLogError(AppServer, "CastingPlayer::ConnectionContext() Device Connection failure callback called with %" CHIP_ERROR_FORMAT, error.Format());
ConnectionContext * connectionContext = static_cast(context);
VerifyOrReturn(connectionContext != nullptr && connectionContext->mTargetCastingPlayer != nullptr,
- ChipLogError(AppServer, "Invalid ConnectionContext received in DeviceConnection failure callback"));
+ ChipLogError(AppServer, "CastingPlayer::ConnectionContext() Invalid ConnectionContext received in DeviceConnection failure callback"));
connectionContext->mTargetCastingPlayer->mConnectionState = CASTING_PLAYER_NOT_CONNECTED;
connectionContext->mOnDeviceConnectionFailureFn(connectionContext->mClientContext, peerId, error);
delete connectionContext;
diff --git a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h
index 0802765bf37dd7..d4d5ae0d4232b0 100644
--- a/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h
+++ b/examples/tv-casting-app/tv-casting-common/core/CastingPlayer.h
@@ -100,7 +100,19 @@ class CastingPlayer : public std::enable_shared_from_this
/**
* @brief Get the CastingPlayer object targeted currently (may not be connected)
*/
- static CastingPlayer * GetTargetCastingPlayer() { return mTargetCastingPlayer; }
+ static CastingPlayer * GetTargetCastingPlayer() {
+ ChipLogProgress(AppServer, "CastingPlayer::GetTargetCastingPlayer() called");
+ std::shared_ptr sharedPtr = mTargetCastingPlayer.lock();
+ CastingPlayer* rawPtr = nullptr;
+ if (sharedPtr) {
+ rawPtr = sharedPtr.get();
+ ChipLogProgress(AppServer, "CastingPlayer::GetTargetCastingPlayer() Got rawPtr from mTargetCastingPlayer, sharedPtr reference count: %lu", sharedPtr.use_count());
+ sharedPtr.reset();
+ } else {
+ ChipLogError(AppServer, "CastingPlayer::GetTargetCastingPlayer() The shared pointer observed by mTargetCastingPlayer has expired (become nullptr)");
+ }
+ return rawPtr;
+ }
/**
* @brief Compares based on the Id
@@ -257,12 +269,23 @@ class CastingPlayer : public std::enable_shared_from_this
void SetFabricIndex(chip::FabricIndex fabricIndex) { mAttributes.fabricIndex = fabricIndex; }
+ /**
+ * @brief Return the current state of the CastingPlayer
+ */
+ ConnectionState GetConnectionState() const {
+ return mConnectionState;
+ }
+
private:
std::vector> mEndpoints;
ConnectionState mConnectionState = CASTING_PLAYER_NOT_CONNECTED;
CastingPlayerAttributes mAttributes;
IdentificationDeclarationOptions mIdOptions;
- static CastingPlayer * mTargetCastingPlayer;
+ // This is a std::weak_ptr. A std::weak_ptr is a non-owning reference to an object managed by one
+ // or more std::shared_ptr instances. When the last std::shared_ptr instance that owns the managed
+ // object is destroyed or reset, the object itself is automatically destroyed, and all
+ // std::weak_ptr instances that reference that object become expired.
+ static memory::Weak mTargetCastingPlayer;
uint16_t mCommissioningWindowTimeoutSec = kCommissioningWindowTimeoutSec;
ConnectCallback mOnCompleted = {};
diff --git a/examples/tv-casting-app/tv-casting-common/core/CastingPlayerDiscovery.cpp b/examples/tv-casting-app/tv-casting-common/core/CastingPlayerDiscovery.cpp
index 531de966810163..4be75dfd6f8cc3 100644
--- a/examples/tv-casting-app/tv-casting-common/core/CastingPlayerDiscovery.cpp
+++ b/examples/tv-casting-app/tv-casting-common/core/CastingPlayerDiscovery.cpp
@@ -63,16 +63,55 @@ CHIP_ERROR CastingPlayerDiscovery::StartDiscovery(uint32_t deviceTypeFilter)
CHIP_ERROR CastingPlayerDiscovery::StopDiscovery()
{
- ChipLogProgress(Discovery, "CastingPlayerDiscovery::StopDiscovery() called");
+ ChipLogProgress(Discovery, "CastingPlayerDiscovery::StopDiscovery() mCastingPlayers: %lu, mCastingPlayersInternal: %lu", mCastingPlayers.size(), mCastingPlayersInternal.size());
VerifyOrReturnError(mState == DISCOVERY_RUNNING, CHIP_ERROR_INCORRECT_STATE);
ReturnErrorOnFailure(mCommissionableNodeController.StopDiscovery());
+ // Clear mCastingPlayersInternal of disconnected CastingPlayers
+ ClearDisconnectedCastingPlayersInternal();
+ for (const auto& player : mCastingPlayers)
+ {
+ mCastingPlayersInternal.push_back(player);
+ }
+ // Clear mCastingPlayers of all CastingPlayers
mCastingPlayers.clear();
mState = DISCOVERY_READY;
return CHIP_NO_ERROR;
}
+void CastingPlayerDiscovery::ClearDisconnectedCastingPlayersInternal()
+{
+ ChipLogProgress(Discovery, "CastingPlayerDiscovery::ClearDisconnectedCastingPlayersInternal() mCastingPlayersInternal: %lu", mCastingPlayersInternal.size());
+ // Only clear the CastingPlayers in mCastingPlayersInternal with ConnectionState == CASTING_PLAYER_NOT_CONNECTED
+ ClearDisconnectedCastingPlayers(mCastingPlayersInternal);
+}
+
+void CastingPlayerDiscovery::ClearDisconnectedCastingPlayers(std::vector>& castingPlayers)
+{
+ ChipLogProgress(Discovery, "CastingPlayerDiscovery::ClearDisconnectedCastingPlayers() called");
+ for (auto it = castingPlayers.begin(); it != castingPlayers.end();)
+ {
+ auto& player = *it;
+ if (player->GetConnectionState() == CASTING_PLAYER_NOT_CONNECTED)
+ {
+ ChipLogProgress(Discovery, "CastingPlayerDiscovery::ClearDisconnectedCastingPlayers() Removing disconnected CastingPlayer: %s with reference count: %lu",
+ player->GetDeviceName(), player.use_count());
+ it = castingPlayers.erase(it);
+ }
+ else
+ {
+ ++it; // Move to the next element if the current one is not removed
+ }
+ }
+}
+
+void CastingPlayerDiscovery::ClearCastingPlayersInternal()
+{
+ ChipLogProgress(Discovery, "CastingPlayerDiscovery::ClearCastingPlayersInternal()");
+ mCastingPlayersInternal.clear();
+}
+
void DeviceDiscoveryDelegateImpl::OnDiscoveredDevice(const chip::Dnssd::CommissionNodeData & nodeData)
{
ChipLogProgress(Discovery, "DeviceDiscoveryDelegateImpl::OnDiscoveredDevice() called");
diff --git a/examples/tv-casting-app/tv-casting-common/core/CastingPlayerDiscovery.h b/examples/tv-casting-app/tv-casting-common/core/CastingPlayerDiscovery.h
index 24bbb00ce4907b..773939b7fe61ac 100644
--- a/examples/tv-casting-app/tv-casting-common/core/CastingPlayerDiscovery.h
+++ b/examples/tv-casting-app/tv-casting-common/core/CastingPlayerDiscovery.h
@@ -52,7 +52,7 @@ class DLL_EXPORT DiscoveryDelegate
virtual void HandleOnUpdated(memory::Strong players) = 0;
// virtual void HandleOnRemoved(memory::Strong players) = 0;
};
-
+class CastingPlayer; // Forward declaration of the CastingPlayer class
class CastingPlayerDiscovery;
/**
@@ -79,6 +79,10 @@ class CastingPlayerDiscovery
private:
std::vector> mCastingPlayers;
+ // This vector is used to store CastingPlayers that we might want to connect to. This ensures
+ // that CastingPlayers are not deleted prior to calling verify VerifyOrEstablishConnection() on
+ // the CastingPlayer we want to connect to.
+ std::vector> mCastingPlayersInternal;
DeviceDiscoveryDelegateImpl mDelegate;
CastingPlayerDiscovery();
@@ -90,8 +94,29 @@ class CastingPlayerDiscovery
chip::Controller::CommissionableNodeController mCommissionableNodeController;
CastingPlayerDiscoveryState mState = DISCOVERY_NOT_READY;
+ /**
+ * @brief Clear CastingPlayers in mCastingPlayersInternal with ConnectionState == CASTING_PLAYER_NOT_CONNECTED
+ */
+ void ClearDisconnectedCastingPlayersInternal();
+
+ /**
+ * @brief Clear CastingPlayers in the specified vector with ConnectionState == CASTING_PLAYER_NOT_CONNECTED
+ *
+ * @param castingPlayers vector of CastingPlayers to clear
+ */
+ void ClearDisconnectedCastingPlayers(std::vector>& castingPlayers);
+
+ /**
+ * @brief Clear all CastingPlayers in mCastingPlayersInternal
+ */
+ void ClearCastingPlayersInternal();
+
public:
static CastingPlayerDiscovery * GetInstance();
+ ~CastingPlayerDiscovery() {
+ mCastingPlayers.clear();
+ mCastingPlayersInternal.clear();
+ }
/**
* @brief Starts the discovery for CastingPlayers
@@ -126,6 +151,7 @@ class CastingPlayerDiscovery
std::vector> GetCastingPlayers() { return mCastingPlayers; }
friend class DeviceDiscoveryDelegateImpl;
+ friend class CastingPlayer;
};
}; // namespace core
diff --git a/examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp b/examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp
index 9793b6c5fc6316..c719b3b8b51383 100644
--- a/examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp
+++ b/examples/tv-casting-app/tv-casting-common/support/CastingStore.cpp
@@ -40,7 +40,7 @@ CastingStore * CastingStore::GetInstance()
CHIP_ERROR CastingStore::AddOrUpdate(core::CastingPlayer castingPlayer)
{
- ChipLogProgress(AppServer, "CastingStore::AddOrUpdate");
+ ChipLogProgress(AppServer, "CastingStore::AddOrUpdate() called with CastingPlayer deviceName: %s", castingPlayer.GetDeviceName());
// Read cache of CastingPlayers
std::vector castingPlayers = ReadAll();
@@ -56,20 +56,20 @@ CHIP_ERROR CastingStore::AddOrUpdate(core::CastingPlayer castingPlayer)
{
unsigned index = (unsigned int) std::distance(castingPlayers.begin(), it);
castingPlayers[index] = castingPlayer;
- ChipLogProgress(AppServer, "CastingStore::AddOrUpdate updating CastingPlayer in CastingStore cache");
+ ChipLogProgress(AppServer, "CastingStore::AddOrUpdate() updating CastingPlayer in CastingStore cache");
return WriteAll(castingPlayers); // return early
}
}
// add *new* castingPlayer to CastingStore cache
castingPlayers.push_back(castingPlayer);
- ChipLogProgress(AppServer, "CastingStore::AddOrUpdate adding new CastingPlayer in CastingStore cache");
+ ChipLogProgress(AppServer, "CastingStore::AddOrUpdate() adding new CastingPlayer in CastingStore cache");
return WriteAll(castingPlayers);
}
std::vector CastingStore::ReadAll()
{
- ChipLogProgress(AppServer, "CastingStore::ReadAll called");
+ ChipLogProgress(AppServer, "CastingStore::ReadAll() called");
CHIP_ERROR err = CHIP_NO_ERROR;
std::vector castingPlayers;
@@ -79,7 +79,7 @@ std::vector CastingStore::ReadAll()
kCastingStoreDataMaxBytes, &castingStoreDataSize);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector(),
ChipLogError(AppServer, "KeyValueStoreMgr.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
- ChipLogProgress(AppServer, "CastingStore::ReadAll Read TLV(CastingStoreData) from KVS store with size: %lu bytes",
+ ChipLogProgress(AppServer, "CastingStore::ReadAll() Read TLV(CastingStoreData) from KVS store with size: %lu bytes",
static_cast(castingStoreDataSize));
chip::TLV::TLVReader reader;
@@ -106,7 +106,7 @@ std::vector CastingStore::ReadAll()
err = reader.Get(version);
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector(),
ChipLogError(AppServer, "TLVReader.Get failed %" CHIP_ERROR_FORMAT, err.Format()));
- ChipLogProgress(AppServer, "CastingStore::ReadAll TLV(CastingStoreData) version: %d", version);
+ ChipLogProgress(AppServer, "CastingStore::ReadAll() TLV(CastingStoreData) version: %d", version);
// Entering CastingPlayers container
err = reader.Next();
@@ -445,7 +445,7 @@ std::vector CastingStore::ReadAll()
VerifyOrReturnValue(err == CHIP_NO_ERROR, std::vector(),
ChipLogError(AppServer, "TLVReader.ExitContainer failed %" CHIP_ERROR_FORMAT, err.Format()));
- ChipLogProgress(AppServer, "CastingStore::ReadAll CastingPlayers size: %lu", static_cast(castingPlayers.size()));
+ ChipLogProgress(AppServer, "CastingStore::ReadAll() CastingPlayers size: %lu", static_cast(castingPlayers.size()));
return castingPlayers;
}
diff --git a/examples/tv-casting-app/tv-casting-common/support/ChipDeviceEventHandler.cpp b/examples/tv-casting-app/tv-casting-common/support/ChipDeviceEventHandler.cpp
index bb226a15298229..30746436256da9 100644
--- a/examples/tv-casting-app/tv-casting-common/support/ChipDeviceEventHandler.cpp
+++ b/examples/tv-casting-app/tv-casting-common/support/ChipDeviceEventHandler.cpp
@@ -35,7 +35,7 @@ bool ChipDeviceEventHandler::sUdcInProgress = false;
void ChipDeviceEventHandler::Handle(const chip::DeviceLayer::ChipDeviceEvent * event, intptr_t arg)
{
- ChipLogProgress(AppServer, "ChipDeviceEventHandler::Handle called");
+ ChipLogProgress(AppServer, "ChipDeviceEventHandler::Handle() called");
bool runPostCommissioning = false;
chip::NodeId targetNodeId = 0;
@@ -65,16 +65,17 @@ void ChipDeviceEventHandler::Handle(const chip::DeviceLayer::ChipDeviceEvent * e
CastingPlayer::GetTargetCastingPlayer()->FindOrEstablishSession(
nullptr,
[](void * context, chip::Messaging::ExchangeManager & exchangeMgr, const chip::SessionHandle & sessionHandle) {
- ChipLogProgress(AppServer, "ChipDeviceEventHandler::Handle: Connection to CastingPlayer successful");
+ ChipLogProgress(AppServer, "ChipDeviceEventHandler::Handle() Connection to CastingPlayer successful");
CastingPlayer::GetTargetCastingPlayer()->mConnectionState = CASTING_PLAYER_CONNECTED;
// this async call will Load all the endpoints with their respective attributes into the TargetCastingPlayer
// persist the TargetCastingPlayer information into the CastingStore and call mOnCompleted()
EndpointListLoader::GetInstance()->Initialize(&exchangeMgr, &sessionHandle);
+ ChipLogProgress(AppServer, "ChipDeviceEventHandler::Handle() calling EndpointListLoader::GetInstance()->Load()");
EndpointListLoader::GetInstance()->Load();
},
[](void * context, const chip::ScopedNodeId & peerId, CHIP_ERROR error) {
- ChipLogError(AppServer, "ChipDeviceEventHandler::Handle: Connection to CastingPlayer failed");
+ ChipLogError(AppServer, "ChipDeviceEventHandler::Handle(): Connection to CastingPlayer failed");
CastingPlayer::GetTargetCastingPlayer()->mConnectionState = CASTING_PLAYER_NOT_CONNECTED;
CHIP_ERROR err = support::CastingStore::GetInstance()->Delete(*CastingPlayer::GetTargetCastingPlayer());
if (err != CHIP_NO_ERROR)
@@ -84,7 +85,7 @@ void ChipDeviceEventHandler::Handle(const chip::DeviceLayer::ChipDeviceEvent * e
VerifyOrReturn(CastingPlayer::GetTargetCastingPlayer()->mOnCompleted);
CastingPlayer::GetTargetCastingPlayer()->mOnCompleted(error, nullptr);
- CastingPlayer::mTargetCastingPlayer = nullptr;
+ CastingPlayer::mTargetCastingPlayer.reset();
});
}
}
@@ -100,7 +101,7 @@ void ChipDeviceEventHandler::HandleFailSafeTimerExpired()
CastingPlayer::GetTargetCastingPlayer()->mConnectionState = CASTING_PLAYER_NOT_CONNECTED;
CastingPlayer::GetTargetCastingPlayer()->mOnCompleted(CHIP_ERROR_TIMEOUT, nullptr);
CastingPlayer::GetTargetCastingPlayer()->mOnCompleted = nullptr;
- CastingPlayer::GetTargetCastingPlayer()->mTargetCastingPlayer = nullptr;
+ CastingPlayer::GetTargetCastingPlayer()->mTargetCastingPlayer.reset();
return;
}