Skip to content

Commit

Permalink
tv-casting-app fix double call to OnCompleted() on connection success
Browse files Browse the repository at this point in the history
Fixing spelling

Fixing CI build documentation error

Fixing CI build documentation error2

Fixing CI build documentation error3

Fixing CI build documentation error4
  • Loading branch information
pgregorr-amazon committed Jan 14, 2025
1 parent 5bd63d5 commit 96e1100
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 14 deletions.
11 changes: 9 additions & 2 deletions examples/tv-casting-app/APIs.md
Original file line number Diff line number Diff line change
Expand Up @@ -71,14 +71,21 @@ In order to illustrate these steps, refer to the figure below
The Casting Client is expected to consume the Matter TV Casting library built
for its respective platform which implements the APIs described in this
document. Refer to the tv-casting-app READMEs for [Linux](linux/README.md),
Android and [iOS](darwin/TvCasting/README.md) to understand how to build and
consume each platform's specific libraries. The libraries MUST be built with the
[Android](https://github.com/project-chip/connectedhomeip/blob/master/examples/tv-casting-app/android/README.md)
and [iOS](darwin/TvCasting/README.md) to understand how to build and consume
each platform's specific libraries. The libraries MUST be built with the
client's specific values for `CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID` and
`CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID` updated in the
[CHIPProjectAppConfig.h](tv-casting-common/include/CHIPProjectAppConfig.h) file.
Other values like the `CHIP_DEVICE_CONFIG_DEVICE_NAME` may be updated as well to
correspond to the client being built.

`CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID` and `CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID`
can be obtained during the CSA certification of your mobile app. The Matter SDK
has pre-configured sample/test values for them in the
[CHIPDeviceConfig.h](https://github.com/project-chip/connectedhomeip/blob/master/src/include/platform/CHIPDeviceConfig.h)
file.

### Initialize the Casting Client

_{Complete Initialization examples: [Linux](linux/simple-app.cpp) |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ public void handle(CommissionerDeclaration cd) {

FragmentActivity activity = getActivity();
// Prevent possible NullPointerException. This callback could be called when
// this Fragment is not attached to its host activity or when the fragment's
// this fragment is not attached to its host activity or when the fragment's
// lifecycle is not in a valid state for interacting with the activity.
if (activity != null && !activity.isFinishing()) {
activity.runOnUiThread(
Expand Down
44 changes: 42 additions & 2 deletions examples/tv-casting-app/android/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ commissioning mode, advertises itself as a Commissionable Node and gets
commissioned. Then it allows the user to send Matter ContentLauncher commands to
the TV.

Refer to the
[Matter Casting APIs documentation](https://project-chip.github.io/connectedhomeip-doc/examples/tv-casting-app/APIs.html)
to build the Matter “Casting Client” into your consumer-facing mobile app.

<hr>

- [Matter TV Casting Android App Example](#matter-tv-casting-android-app-example)
Expand All @@ -15,6 +19,8 @@ the TV.
- [Gradle \& JDK Version](#gradle--jdk-version)
- [Preparing for build](#preparing-for-build)
- [Building \& Installing the app](#building--installing-the-app)
- [Common build environment issues](#common-build-environment-issues)
- [Running the app](#running-the-app)

<hr>

Expand Down Expand Up @@ -50,10 +56,24 @@ We are using Gradle 7.1.1 for all android project which does not support Java 17
(https://docs.gradle.org/current/userguide/compatibility.html) while the default
JDK version on MacOS for Apple Silicon is 'openjdk 17.0.1' or above.

Using JDK bundled with Android Studio will help with that.
If you attempt to build with an incompatible Java version, you may encounter the
following error:

```text
Unsupported class file major version XX
```

This error occurs when the Java version being used is not compatible with the
Gradle version in your project.

See the
[Building Android](../../../docs/platforms/android/android_building.md#gradle--jdk-version)
guide for more info about the supported Gradle & JDK Version.

You can verify your current Java version by running:

```shell
export JAVA_HOME=/Applications/Android\ Studio.app/Contents/jre/Contents/Home/
java -version
```

<hr>
Expand Down Expand Up @@ -107,3 +127,23 @@ adb install out/android-$TARGET_CPU-tv-casting-app/outputs/apk/debug/app-debug.a
You can use Android Studio to edit the Android app itself and run it after
build_examples.py, but you will not be able to edit Matter Android code from
`src/controller/java`, or other Matter C++ code within Android Studio.
## Common build environment issues
1. If you see an error like `kotlinc: command not found`, install the Kotlin in
your build environment. Eg. on MacOS, this can be done with the command:
```shell
brew install kotlin
```
## Running the app
This example Matter TV Casting Android app can be tested with the following
video players:
1. With the
[example Matter tv-app](https://github.com/project-chip/connectedhomeip/tree/master/examples/tv-app)
running on a Raspberry Pi - works out of the box.
2. With a FireTV device - requires your Amazon Customer ID to be allow-listed
first.
17 changes: 17 additions & 0 deletions examples/tv-casting-app/darwin/TvCasting/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,19 @@ commissioning mode, advertises itself as a Commissionable Node and gets
commissioned. Then it allows the user to send Matter ContentLauncher commands to
the TV.

Refer to the
[Matter Casting APIs documentation](https://project-chip.github.io/connectedhomeip-doc/examples/tv-casting-app/APIs.html)
to build the Matter “Casting Client” into your consumer-facing mobile app.

---

- [Matter TV Casting iOS App Example](#matter-tv-casting-ios-app-example)
- [Building the Application](#building-the-application)
- [Building through command line](#building-through-command-line)
- [Compilation Fixes](#compilation-fixes)
- [Installing the Application](#installing-the-application)
- [Debugging](#debugging)
- [Running the Application](#running-the-application)

---

Expand Down Expand Up @@ -98,3 +104,14 @@ the run button once more.

Use the "TvCasting" scheme when building to enable debugging. If you wish to
build the app without any debugging symbols, use the "TvCasting Release" scheme.

## Running the Application

This example Matter TV Casting iOS application can be tested with the following
video players:

1. With the
[example Matter tv-app](https://github.com/project-chip/connectedhomeip/tree/master/examples/tv-app)
running on a Raspberry Pi - works out of the box.
2. With a FireTV device - requires your Amazon Customer ID to be allow-listed
first.
20 changes: 16 additions & 4 deletions examples/tv-casting-app/linux/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ select one, sends the TV a User Directed Commissioning request, enters
commissioning mode, advertises itself as a Commissionable Node and gets
commissioned. Then it allows the user to send CHIP commands to the TV.

Refer to the
[Matter Casting APIs documentation](https://project-chip.github.io/connectedhomeip-doc/examples/tv-casting-app/APIs.html)
to build the Matter “Casting Client” into your consumer-facing mobile app.

<hr>

- [CHIP TV Casting App Example](#chip-tv-casting-app-example)
Expand Down Expand Up @@ -63,10 +67,15 @@ commissioned. Then it allows the user to send CHIP commands to the TV.

### Commissioning the tv-casting-app

The tv-casting-app will automatically discover video players and print these out
upon startup. The user-directed-commissioning (UDC) process can be initiated
using the shell by specifying the index of the discovered video player in the
printed list.
This example Matter TV Casting iOS application can be tested with the following
video players:

1. With the
[example Matter tv-app](https://github.com/project-chip/connectedhomeip/tree/master/examples/tv-app)
running on a Raspberry Pi - works out of the box. The tv-casting-app will
automatically discover video players and print these out upon startup. The
user-directed-commissioning (UDC) process can be initiated using the shell by
specifying the index of the discovered video player in the printed list.

- Initiate UDC for the discovered video player with index 0

Expand All @@ -81,6 +90,9 @@ printed list.

tv-casting-app> cast discover

2. With a FireTV device - requires your Amazon Customer ID to be allow-listed
first.

### Re-Running the Example on Linux with Cached Fabrics

After successfully commissioning the tv-casting-app onto a fabric the app can be
Expand Down
3 changes: 3 additions & 0 deletions examples/tv-casting-app/linux/simple-app-helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,12 +318,15 @@ void ConnectionHandler(CHIP_ERROR err, matter::casting::core::CastingPlayer * ca
castingPlayer->GetId(), endpoints[index]->GetId());

// demonstrate invoking a command
ChipLogProgress(AppServer, "simple-app-helper.cpp::ConnectionHandler() calling InvokeContentLauncherLaunchURL()");
InvokeContentLauncherLaunchURL(endpoints[index]);

// demonstrate reading an attribute
ChipLogProgress(AppServer, "simple-app-helper.cpp::ConnectionHandler() calling ReadApplicationBasicVendorID()");
ReadApplicationBasicVendorID(endpoints[index]);

// demonstrate subscribing to an attribute
ChipLogProgress(AppServer, "simple-app-helper.cpp::ConnectionHandler() calling SubscribeToMediaPlaybackCurrentState()");
SubscribeToMediaPlaybackCurrentState(endpoints[index]);
}
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ void ChipDeviceEventHandler::Handle(const chip::DeviceLayer::ChipDeviceEvent * e
if (event->Type == chip::DeviceLayer::DeviceEventType::kFailSafeTimerExpired &&
CastingPlayer::GetTargetCastingPlayer()->mConnectionState == CASTING_PLAYER_CONNECTING)
{
ChipLogProgress(AppServer, "ChipDeviceEventHandler::Handle() event kFailSafeTimerExpired");
HandleFailSafeTimerExpired();
}
else if (event->Type == chip::DeviceLayer::DeviceEventType::kBindingsChangedViaCluster &&
Expand All @@ -53,16 +54,19 @@ void ChipDeviceEventHandler::Handle(const chip::DeviceLayer::ChipDeviceEvent * e
}
else if (event->Type == chip::DeviceLayer::DeviceEventType::kCommissioningComplete)
{
// True when device completes initial commissioning (PASE).
// Note: Not triggered for subsequent CASE sessions established via CastingPlayer::FindOrEstablishSession()
HandleCommissioningComplete(event, arg, runPostCommissioning, targetNodeId, targetFabricIndex);
}

// Run post commissioing for kBindingsChangedViaCluster and kCommissioningComplete events.
if (runPostCommissioning)
{
sUdcInProgress = false;
CastingPlayer::GetTargetCastingPlayer()->SetNodeId(targetNodeId);
CastingPlayer::GetTargetCastingPlayer()->SetFabricIndex(targetFabricIndex);

ChipLogProgress(AppServer, "ChipDeviceEventHandler::Handle() calling FindOrEstablishSession()");
ChipLogProgress(AppServer, "ChipDeviceEventHandler::Handle() calling CastingPlayer FindOrEstablishSession()");
CastingPlayer::GetTargetCastingPlayer()->FindOrEstablishSession(
nullptr,
[](void * context, chip::Messaging::ExchangeManager & exchangeMgr, const chip::SessionHandle & sessionHandle) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ CHIP_ERROR EndpointListLoader::Load()

if (!isLoadingRequired)
{
ChipLogProgress(AppServer, "EndpointListLoader::Load found no new endpoints to load");
ChipLogProgress(AppServer,
"EndpointListLoader::Load() found no new endpoints to load. Calling EndpointListLoader::Complete()");
mPendingAttributeReads = 0;
Complete();
}
Expand Down Expand Up @@ -172,16 +173,32 @@ void EndpointListLoader::Complete()
mNewEndpointsToLoad = 0;

// done loading endpoints, store TargetCastingPlayer
ChipLogProgress(AppServer, "EndpointListLoader::Complete() Calling CastingStore::AddOrUpdate()");
CHIP_ERROR err = support::CastingStore::GetInstance()->AddOrUpdate(*CastingPlayer::GetTargetCastingPlayer());
if (err != CHIP_NO_ERROR)
{
ChipLogError(AppServer, "CastingStore::AddOrUpdate() failed. Err: %" CHIP_ERROR_FORMAT, err.Format());
}

// callback client OnCompleted
// Only trigger OnCompleted callback for target CastingPlayer when it has loaded endpoints (count >= 1)
// Note: After initial commissioning (kCommissioningComplete event), endpoints will be 0.
// CastingPlayer Endpoints are populated later, after receiving the kBindingsChangedViaCluster device event.
VerifyOrReturn(CastingPlayer::GetTargetCastingPlayer()->mOnCompleted,
ChipLogError(AppServer, "EndpointListLoader::Complete() mOnCompleted() not found"));
CastingPlayer::GetTargetCastingPlayer()->mOnCompleted(CHIP_NO_ERROR, CastingPlayer::GetTargetCastingPlayer());
ChipLogError(AppServer, "EndpointListLoader::Complete() OnCompleted() not found"));

std::vector<matter::casting::memory::Strong<matter::casting::core::Endpoint>> endpoints =
CastingPlayer::GetTargetCastingPlayer()->GetEndpoints();
if (endpoints.size() > 0)
{
ChipLogProgress(AppServer,
"EndpointListLoader::Complete() Target CastingPlayer endpoints: %d, calling client's OnCompleted()",
static_cast<int>(endpoints.size()));
CastingPlayer::GetTargetCastingPlayer()->mOnCompleted(CHIP_NO_ERROR, CastingPlayer::GetTargetCastingPlayer());
}
else
{
ChipLogProgress(AppServer, "EndpointListLoader::Complete() Target CastingPlayer endpoints pending setup.");
}
}
}

Expand Down

0 comments on commit 96e1100

Please sign in to comment.