Skip to content

Commit

Permalink
android/tv-casting-app: Implemented commands and attributes using CHI…
Browse files Browse the repository at this point in the history
…PInteractionClient.jar
  • Loading branch information
sharadb-amazon committed Apr 16, 2024
1 parent 6ba907e commit 01a26df
Show file tree
Hide file tree
Showing 20 changed files with 808 additions and 39 deletions.
155 changes: 148 additions & 7 deletions examples/tv-casting-app/APIs.md
Original file line number Diff line number Diff line change
Expand Up @@ -830,7 +830,7 @@ func connect(selectedCastingPlayer: MCCastingPlayer?) {
### Select an Endpoint on the Casting Player
_{Complete Endpoint selection examples: [Linux](linux/simple-app-helper.cpp) |
[Android](android/App/app/src/main/java/com/matter/casting/ContentLauncherLaunchURLExampleFragment.java)
[Android](android/App/app/src/main/java/com/matter/casting/EndpointSelectorExample.java)
|
[iOS](darwin/TvCasting/TvCasting/MCContentLauncherLaunchURLExampleViewModel.swift)}_
Expand Down Expand Up @@ -905,18 +905,25 @@ Once the Casting Client has selected an `Endpoint`, it is ready to
[issue commands](#issuing-commands) to it, [read](#read-operations) current
playback state, and [subscribe](#subscriptions) to playback events.
On Linux refer to the following platform specific files:
Refer to the following platform specific files, to find the list of clusters,
commands and attributes, with their request/response types available for use
with the Matter TV Casting library.
For Linux, refer to the following files:
1. For a list of clusters, commands and attributes supported by the Matter TV
Casting library:
1. For a list of supported clusters, commands and attributes:
[tv-casting-common/clusters/Clusters.h](tv-casting-common/clusters/Clusters.h)
2. For the IDs and request / response types to use with these APIs:
[/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h](/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h)
On iOS refer to the following platform specific files:
For Android, refer to the following files:
1. For a list of supported clusters, commands and attributes:
[/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java](/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java)
1. For a list of clusters, commands and attributes supported by the Matter TV
Casting library:
On iOS, refer to the following files:
1. For a list of supported clusters, commands and attribute:
[darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCClusterObjects.h](darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCClusterObjects.h)
2. For the IDs and request / response types to use with the commands:
[darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCCommandObjects.h](darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCCommandObjects.h)
Expand All @@ -929,6 +936,8 @@ On iOS refer to the following platform specific files:
### Issuing Commands
_{Complete Command invocation examples: [Linux](linux/simple-app-helper.cpp) |
[Android](android/App/app/src/main/java/com/matter/casting/ContentLauncherLaunchURLExampleFragment.java)
|
[iOS](darwin/TvCasting/TvCasting/MCContentLauncherLaunchURLExampleViewModel.swift)}_
The Casting Client can get a reference to an `Endpoint` on a `CastingPlayer`,
Expand Down Expand Up @@ -975,6 +984,51 @@ void InvokeContentLauncherLaunchURL(matter::casting::memory::Strong<matter::cast
}
```
On Android, given an `Endpoint`, it can send a `LaunchURL` command (part of the
Content Launcher cluster) by calling the `launchURL` API on a
`ChipClusters.ContentLauncherCluster` object.
```java
// get ChipClusters.ContentLauncherCluster from the endpoint
ChipClusters.ContentLauncherCluster cluster =
endpoint.getCluster(ChipClusters.ContentLauncherCluster.class);
if (cluster == null) {
Log.e(TAG, "Could not get ContentLauncherCluster for endpoint with ID: " + endpoint.getId());
return;
}
// call launchURL on the cluster object while passing in a
// ChipClusters.ContentLauncherCluster.LauncherResponseCallback and request parameters
cluster.launchURL(
new ChipClusters.ContentLauncherCluster.LauncherResponseCallback() {
@Override
public void onSuccess(Integer status, Optional<String> data) {
Log.d(TAG, "LaunchURL success. Status: " + status + ", Data: " + data);
new Handler(Looper.getMainLooper())
.post(
() -> {
TextView launcherResult = getView().findViewById(R.id.launcherResult);
launcherResult.setText(
"LaunchURL result\nStatus: " + status + ", Data: " + data);
});
}
@Override
public void onError(Exception error) {
Log.e(TAG, "LaunchURL failure " + error);
new Handler(Looper.getMainLooper())
.post(
() -> {
TextView launcherResult = getView().findViewById(R.id.launcherResult);
launcherResult.setText("LaunchURL result\nError: " + error);
});
}
},
contentUrl,
Optional.of(contentDisplayString),
Optional.empty());
```
On iOS, given an `MCEndpoint` endpoint, it can send a `LaunchURL` command (part
of the Content Launcher cluster) by calling the `invoke` API on a
`MCContentLauncherClusterLaunchURLCommand`
Expand Down Expand Up @@ -1033,6 +1087,8 @@ timedInvokeTimeoutMs: 5000) // time out after 5000ms
### Read Operations
_{Complete Attribute Read examples: [Linux](linux/simple-app-helper.cpp) |
[Android](android/App/app/src/main/java/com/matter/casting/ApplicationBasicReadVendorIDExampleFragment.java)
|
[iOS](darwin/TvCasting/TvCasting/MCApplicationBasicReadVendorIDExampleViewModel.swift)}_
The `CastingClient` may read an Attribute from the `Endpoint` on the
Expand Down Expand Up @@ -1080,6 +1136,45 @@ void ReadApplicationBasicVendorID(matter::casting::memory::Strong<matter::castin
}
```
On Android, given an `Endpoint`, the `VendorID` can be read, by calling
`readVendorIDAttribute` on the `ChipClusters.ApplicationBasicCluster` object.
```java
// get ChipClusters.ApplicationBasic from the endpoint
ChipClusters.ApplicationBasicCluster cluster = endpoint.getCluster(ChipClusters.ApplicationBasicCluster.class);
if (cluster == null) {
Log.e(TAG, "Could not get ApplicationBasicCluster for endpoint with ID: " + endpoint.getId());
return;
}
// call readVendorIDAttribute on the cluster object while passing in a
// ChipClusters.IntegerAttributeCallback
cluster.readVendorIDAttribute(new ChipClusters.IntegerAttributeCallback() {
@Override
public void onSuccess(int value) {
Log.d(TAG, "ReadVendorID success. Value: " + value);
new Handler(Looper.getMainLooper())
.post(
() -> {
TextView vendorIdResult = getView().findViewById(R.id.vendorIdResult);
vendorIdResult.setText(
"Read VendorID result\nValue: " + value );
});
}
@Override
public void onError(Exception error) {
Log.e(TAG, "ReadVendorID failure " + error);
new Handler(Looper.getMainLooper())
.post(
() -> {
TextView vendorIdResult = getView().findViewById(R.id.vendorIdResult);
vendorIdResult.setText("Read VendorID result\nError: " + error);
});
}
});
```
On iOS, given a `MCEndpoint`, the `VendorID` can be read similarly, by calling
the `read` API on the `MCApplicationBasicClusterVendorIDAttribute`
Expand Down Expand Up @@ -1138,6 +1233,9 @@ vendorIDAttribute!.read(nil) { context, before, after, err in
### Subscriptions
_{Complete Attribute subscription examples: [Linux](linux/simple-app-helper.cpp)
|
[Android](android/App/app/src/main/java/com/matter/casting/MediaPlaybackSubscribeToCurrentStateExampleFragment.java)
|
|[iOS](darwin/TvCasting/TvCasting/MCMediaPlaybackSubscribeToCurrentStateExampleViewModel.swift)}_
A Casting Client may subscribe to an attribute on an `Endpoint` of the
Expand Down Expand Up @@ -1187,6 +1285,49 @@ void SubscribeToMediaPlaybackCurrentState(matter::casting::memory::Strong<matter
}
```
On Android, given an `Endpoint`, `CurrentState` can be subscribe to by calling
`subscribeCurrentStateAttribute` on a `ChipClusters.MediaPlaybackCluster`
object.
```java
// get ChipClusters.MediaPlaybackCluster from the endpoint
ChipClusters.MediaPlaybackCluster cluster =
endpoint.getCluster(ChipClusters.MediaPlaybackCluster.class);
if (cluster == null) {
Log.e(
TAG,
"Could not get ApplicationBasicCluster for endpoint with ID: " + endpoint.getId());
return;
}
// call subscribeCurrentStateAttribute on the cluster object while passing in a
// ChipClusters.IntegerAttributeCallback and [0, 1] for min and max interval params
cluster.subscribeCurrentStateAttribute(new ChipClusters.IntegerAttributeCallback() {
@Override
public void onSuccess(int value) {
Log.d(TAG, "Read success on subscription. Value: " + value + " @ " + new Date());
new Handler(Looper.getMainLooper())
.post(
() -> {
TextView currentStateResult = getView().findViewById(R.id.currentStateResult);
currentStateResult.setText(
"Current State result\nValue: " + value );
});
}
@Override
public void onError(Exception error) {
Log.e(TAG, "Read failure on subscription: " + error);
new Handler(Looper.getMainLooper())
.post(
() -> {
TextView currentStateResult = getView().findViewById(R.id.currentStateResult);
currentStateResult.setText("Current State result\nError: " + error);
});
}
}, 0, 1);
```
On iOS, given a `MCEndpoint`, `CurrentState` can be subscribed to by calling the
`subscribe` API on the it can subscribe to the `CurrentState` (part of the Media
Playback Basic cluster) by calling the `Subscribe` API on the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
import com.chip.casting.TvCastingApp;
import com.chip.casting.util.GlobalCastingConstants;
import com.matter.casting.ActionSelectorFragment;
import com.matter.casting.ApplicationBasicReadVendorIDExampleFragment;
import com.matter.casting.ConnectionExampleFragment;
import com.matter.casting.ContentLauncherLaunchURLExampleFragment;
import com.matter.casting.DiscoveryExampleFragment;
import com.matter.casting.InitializationExample;
import com.matter.casting.MediaPlaybackSubscribeToCurrentStateExampleFragment;
import com.matter.casting.PreferencesConfigurationManager;
import com.matter.casting.core.CastingPlayer;
import java.util.Random;
Expand Down Expand Up @@ -85,6 +87,18 @@ public void handleContentLauncherLaunchURLSelected(CastingPlayer selectedCasting
showFragment(ContentLauncherLaunchURLExampleFragment.newInstance(selectedCastingPlayer));
}

@Override
public void handleApplicationBasicReadVendorIDSelected(CastingPlayer selectedCastingPlayer) {
showFragment(ApplicationBasicReadVendorIDExampleFragment.newInstance(selectedCastingPlayer));
}

@Override
public void handleMediaPlaybackSubscribeToCurrentStateSelected(
CastingPlayer selectedCastingPlayer) {
showFragment(
MediaPlaybackSubscribeToCurrentStateExampleFragment.newInstance(selectedCastingPlayer));
}

@Override
public void handleContentLauncherSelected() {
showFragment(ContentLauncherFragment.newInstance(tvCastingApp));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,5 @@ public class GlobalCastingConstants {
public static final int SetupPasscode = 20202021;
public static final int Discriminator = 0xF00;
public static final boolean ChipCastingSimplified =
false; // set this flag to true to demo simplified casting APIs
true; // set this flag to true to demo simplified casting APIs
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ public class ActionSelectorFragment extends Fragment {
private final CastingPlayer selectedCastingPlayer;

private View.OnClickListener selectContentLauncherButtonClickListener;
private View.OnClickListener selectApplicationBasicButtonClickListener;
private View.OnClickListener selectMediaPlaybackButtonClickListener;
private View.OnClickListener disconnectButtonClickListener;

public ActionSelectorFragment(CastingPlayer selectedCastingPlayer) {
Expand Down Expand Up @@ -64,6 +66,16 @@ public View onCreateView(
Log.d(TAG, "handle() called on selectContentLauncherButtonClickListener");
callback.handleContentLauncherLaunchURLSelected(selectedCastingPlayer);
};
this.selectApplicationBasicButtonClickListener =
v -> {
Log.d(TAG, "handle() called on selectApplicationBasicButtonClickListener");
callback.handleApplicationBasicReadVendorIDSelected(selectedCastingPlayer);
};
this.selectMediaPlaybackButtonClickListener =
v -> {
Log.d(TAG, "handle() called on selectMediaPlaybackButtonClickListener");
callback.handleMediaPlaybackSubscribeToCurrentStateSelected(selectedCastingPlayer);
};

this.disconnectButtonClickListener =
v -> {
Expand All @@ -82,6 +94,12 @@ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
getView()
.findViewById(R.id.selectContentLauncherLaunchURLButton)
.setOnClickListener(selectContentLauncherButtonClickListener);
getView()
.findViewById(R.id.selectApplicationBasicReadVendorIDButton)
.setOnClickListener(selectApplicationBasicButtonClickListener);
getView()
.findViewById(R.id.selectMediaPlaybackSubscribeToCurrentStateButton)
.setOnClickListener(selectMediaPlaybackButtonClickListener);

getView().findViewById(R.id.disconnectButton).setOnClickListener(disconnectButtonClickListener);
}
Expand All @@ -91,6 +109,12 @@ public interface Callback {
/** Notifies listener to trigger transition on selection of Content Launcher cluster */
void handleContentLauncherLaunchURLSelected(CastingPlayer selectedCastingPlayer);

/** Notifies listener to trigger transition on selection of Application Basic cluster */
void handleApplicationBasicReadVendorIDSelected(CastingPlayer selectedCastingPlayer);

/** Notifies listener to trigger transition on selection of Media PLayback cluster */
void handleMediaPlaybackSubscribeToCurrentStateSelected(CastingPlayer selectedCastingPlayer);

/** Notifies listener to trigger transition on click of the Disconnect button */
void handleDisconnect();
}
Expand Down
Loading

0 comments on commit 01a26df

Please sign in to comment.