Skip to content

Commit 035d302

Browse files
authoredApr 17, 2024··
android/tv-casting-app: Implemented commands and attributes using CHIPInteractionClient.jar (#33019)
1 parent 294f29e commit 035d302

21 files changed

+830
-42
lines changed
 

‎examples/tv-casting-app/APIs.md

+152-10
Original file line numberDiff line numberDiff line change
@@ -688,15 +688,16 @@ func startDiscovery() {
688688
}
689689
```
690690

691-
Note: You will need to connect with a Casting Player as described below to see
691+
Note: You will need to connect with a Casting Player as described below to se
692692
the list of Endpoints that they support. Refer to the
693693
[Connection](#connect-to-a-casting-player) section for details on how to
694694
discover available endpoints supported by a Casting Player.
695695

696696
### Connect to a Casting Player
697697

698698
_{Complete Connection examples: [Linux](linux/simple-app-helper.cpp) |
699-
[iOS](darwin/TvCasting/TvCasting/MCConnectionExampleViewModel.swift)}_
699+
[Android](android/App/app/src/main/java/com/matter/casting/ConnectionExampleFragment.java)
700+
| [iOS](darwin/TvCasting/TvCasting/MCConnectionExampleViewModel.swift)}_
700701

701702
Each `CastingPlayer` object created during
702703
[Discovery](#discover-casting-players) contains information such as
@@ -830,7 +831,7 @@ func connect(selectedCastingPlayer: MCCastingPlayer?) {
830831
### Select an Endpoint on the Casting Player
831832
832833
_{Complete Endpoint selection examples: [Linux](linux/simple-app-helper.cpp) |
833-
[Android](android/App/app/src/main/java/com/matter/casting/ContentLauncherLaunchURLExampleFragment.java)
834+
[Android](android/App/app/src/main/java/com/matter/casting/EndpointSelectorExample.java)
834835
|
835836
[iOS](darwin/TvCasting/TvCasting/MCContentLauncherLaunchURLExampleViewModel.swift)}_
836837
@@ -863,7 +864,7 @@ On Android, it can select an `Endpoint` as shown below.
863864
```java
864865
private static final Integer SAMPLE_ENDPOINT_VID = 65521;
865866
866-
private Endpoint selectEndpoint()
867+
private Endpoint selectFirstEndpointByVID()
867868
{
868869
Endpoint endpoint = null;
869870
if(selectedCastingPlayer != null)
@@ -905,18 +906,25 @@ Once the Casting Client has selected an `Endpoint`, it is ready to
905906
[issue commands](#issuing-commands) to it, [read](#read-operations) current
906907
playback state, and [subscribe](#subscriptions) to playback events.
907908
908-
On Linux refer to the following platform specific files:
909+
Refer to the following platform specific files, to find the list of clusters,
910+
commands and attributes, with their request/response types available for use
911+
with the Matter TV Casting library.
912+
913+
For Linux, refer to the following files:
909914
910-
1. For a list of clusters, commands and attributes supported by the Matter TV
911-
Casting library:
915+
1. For a list of supported clusters, commands and attributes:
912916
[tv-casting-common/clusters/Clusters.h](tv-casting-common/clusters/Clusters.h)
913917
2. For the IDs and request / response types to use with these APIs:
914918
[/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h](/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h)
915919
916-
On iOS refer to the following platform specific files:
920+
For Android, refer to the following files:
921+
922+
1. For a list of supported clusters, commands and attributes:
923+
[/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java](/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java)
917924
918-
1. For a list of clusters, commands and attributes supported by the Matter TV
919-
Casting library:
925+
On iOS, refer to the following files:
926+
927+
1. For a list of supported clusters, commands and attribute:
920928
[darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCClusterObjects.h](darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCClusterObjects.h)
921929
2. For the IDs and request / response types to use with the commands:
922930
[darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCCommandObjects.h](darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCCommandObjects.h)
@@ -929,6 +937,8 @@ On iOS refer to the following platform specific files:
929937
### Issuing Commands
930938
931939
_{Complete Command invocation examples: [Linux](linux/simple-app-helper.cpp) |
940+
[Android](android/App/app/src/main/java/com/matter/casting/ContentLauncherLaunchURLExampleFragment.java)
941+
|
932942
[iOS](darwin/TvCasting/TvCasting/MCContentLauncherLaunchURLExampleViewModel.swift)}_
933943
934944
The Casting Client can get a reference to an `Endpoint` on a `CastingPlayer`,
@@ -975,6 +985,51 @@ void InvokeContentLauncherLaunchURL(matter::casting::memory::Strong<matter::cast
975985
}
976986
```
977987
988+
On Android, given an `Endpoint`, it can send a `LaunchURL` command (part of the
989+
Content Launcher cluster) by calling the `launchURL` API on a
990+
`ChipClusters.ContentLauncherCluster` object.
991+
992+
```java
993+
// get ChipClusters.ContentLauncherCluster from the endpoint
994+
ChipClusters.ContentLauncherCluster cluster =
995+
endpoint.getCluster(ChipClusters.ContentLauncherCluster.class);
996+
if (cluster == null) {
997+
Log.e(TAG, "Could not get ContentLauncherCluster for endpoint with ID: " + endpoint.getId());
998+
return;
999+
}
1000+
1001+
// call launchURL on the cluster object while passing in a
1002+
// ChipClusters.ContentLauncherCluster.LauncherResponseCallback and request parameters
1003+
cluster.launchURL(
1004+
new ChipClusters.ContentLauncherCluster.LauncherResponseCallback() {
1005+
@Override
1006+
public void onSuccess(Integer status, Optional<String> data) {
1007+
Log.d(TAG, "LaunchURL success. Status: " + status + ", Data: " + data);
1008+
new Handler(Looper.getMainLooper())
1009+
.post(
1010+
() -> {
1011+
TextView launcherResult = getView().findViewById(R.id.launcherResult);
1012+
launcherResult.setText(
1013+
"LaunchURL result\nStatus: " + status + ", Data: " + data);
1014+
});
1015+
}
1016+
1017+
@Override
1018+
public void onError(Exception error) {
1019+
Log.e(TAG, "LaunchURL failure " + error);
1020+
new Handler(Looper.getMainLooper())
1021+
.post(
1022+
() -> {
1023+
TextView launcherResult = getView().findViewById(R.id.launcherResult);
1024+
launcherResult.setText("LaunchURL result\nError: " + error);
1025+
});
1026+
}
1027+
},
1028+
contentUrl,
1029+
Optional.of(contentDisplayString),
1030+
Optional.empty());
1031+
```
1032+
9781033
On iOS, given an `MCEndpoint` endpoint, it can send a `LaunchURL` command (part
9791034
of the Content Launcher cluster) by calling the `invoke` API on a
9801035
`MCContentLauncherClusterLaunchURLCommand`
@@ -1033,6 +1088,8 @@ timedInvokeTimeoutMs: 5000) // time out after 5000ms
10331088
### Read Operations
10341089
10351090
_{Complete Attribute Read examples: [Linux](linux/simple-app-helper.cpp) |
1091+
[Android](android/App/app/src/main/java/com/matter/casting/ApplicationBasicReadVendorIDExampleFragment.java)
1092+
|
10361093
[iOS](darwin/TvCasting/TvCasting/MCApplicationBasicReadVendorIDExampleViewModel.swift)}_
10371094
10381095
The `CastingClient` may read an Attribute from the `Endpoint` on the
@@ -1080,6 +1137,45 @@ void ReadApplicationBasicVendorID(matter::casting::memory::Strong<matter::castin
10801137
}
10811138
```
10821139
1140+
On Android, given an `Endpoint`, the `VendorID` can be read, by calling
1141+
`readVendorIDAttribute` on the `ChipClusters.ApplicationBasicCluster` object.
1142+
1143+
```java
1144+
// get ChipClusters.ApplicationBasic from the endpoint
1145+
ChipClusters.ApplicationBasicCluster cluster = endpoint.getCluster(ChipClusters.ApplicationBasicCluster.class);
1146+
if (cluster == null) {
1147+
Log.e(TAG, "Could not get ApplicationBasicCluster for endpoint with ID: " + endpoint.getId());
1148+
return;
1149+
}
1150+
1151+
// call readVendorIDAttribute on the cluster object while passing in a
1152+
// ChipClusters.IntegerAttributeCallback
1153+
cluster.readVendorIDAttribute(new ChipClusters.IntegerAttributeCallback() {
1154+
@Override
1155+
public void onSuccess(int value) {
1156+
Log.d(TAG, "ReadVendorID success. Value: " + value);
1157+
new Handler(Looper.getMainLooper())
1158+
.post(
1159+
() -> {
1160+
TextView vendorIdResult = getView().findViewById(R.id.vendorIdResult);
1161+
vendorIdResult.setText(
1162+
"Read VendorID result\nValue: " + value );
1163+
});
1164+
}
1165+
1166+
@Override
1167+
public void onError(Exception error) {
1168+
Log.e(TAG, "ReadVendorID failure " + error);
1169+
new Handler(Looper.getMainLooper())
1170+
.post(
1171+
() -> {
1172+
TextView vendorIdResult = getView().findViewById(R.id.vendorIdResult);
1173+
vendorIdResult.setText("Read VendorID result\nError: " + error);
1174+
});
1175+
}
1176+
});
1177+
```
1178+
10831179
On iOS, given a `MCEndpoint`, the `VendorID` can be read similarly, by calling
10841180
the `read` API on the `MCApplicationBasicClusterVendorIDAttribute`
10851181
@@ -1138,6 +1234,9 @@ vendorIDAttribute!.read(nil) { context, before, after, err in
11381234
### Subscriptions
11391235
11401236
_{Complete Attribute subscription examples: [Linux](linux/simple-app-helper.cpp)
1237+
|
1238+
[Android](android/App/app/src/main/java/com/matter/casting/MediaPlaybackSubscribeToCurrentStateExampleFragment.java)
1239+
|
11411240
|[iOS](darwin/TvCasting/TvCasting/MCMediaPlaybackSubscribeToCurrentStateExampleViewModel.swift)}_
11421241
11431242
A Casting Client may subscribe to an attribute on an `Endpoint` of the
@@ -1187,6 +1286,49 @@ void SubscribeToMediaPlaybackCurrentState(matter::casting::memory::Strong<matter
11871286
}
11881287
```
11891288
1289+
On Android, given an `Endpoint`, `CurrentState` can be subscribe to by calling
1290+
`subscribeCurrentStateAttribute` on a `ChipClusters.MediaPlaybackCluster`
1291+
object.
1292+
1293+
```java
1294+
// get ChipClusters.MediaPlaybackCluster from the endpoint
1295+
ChipClusters.MediaPlaybackCluster cluster =
1296+
endpoint.getCluster(ChipClusters.MediaPlaybackCluster.class);
1297+
if (cluster == null) {
1298+
Log.e(
1299+
TAG,
1300+
"Could not get ApplicationBasicCluster for endpoint with ID: " + endpoint.getId());
1301+
return;
1302+
}
1303+
1304+
// call subscribeCurrentStateAttribute on the cluster object while passing in a
1305+
// ChipClusters.IntegerAttributeCallback and [0, 1] for min and max interval params
1306+
cluster.subscribeCurrentStateAttribute(new ChipClusters.IntegerAttributeCallback() {
1307+
@Override
1308+
public void onSuccess(int value) {
1309+
Log.d(TAG, "Read success on subscription. Value: " + value + " @ " + new Date());
1310+
new Handler(Looper.getMainLooper())
1311+
.post(
1312+
() -> {
1313+
TextView currentStateResult = getView().findViewById(R.id.currentStateResult);
1314+
currentStateResult.setText(
1315+
"Current State result\nValue: " + value );
1316+
});
1317+
}
1318+
1319+
@Override
1320+
public void onError(Exception error) {
1321+
Log.e(TAG, "Read failure on subscription: " + error);
1322+
new Handler(Looper.getMainLooper())
1323+
.post(
1324+
() -> {
1325+
TextView currentStateResult = getView().findViewById(R.id.currentStateResult);
1326+
currentStateResult.setText("Current State result\nError: " + error);
1327+
});
1328+
}
1329+
}, 0, 1);
1330+
```
1331+
11901332
On iOS, given a `MCEndpoint`, `CurrentState` can be subscribed to by calling the
11911333
`subscribe` API on the it can subscribe to the `CurrentState` (part of the Media
11921334
Playback Basic cluster) by calling the `Subscribe` API on the

‎examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/app/MainActivity.java

+14
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111
import com.chip.casting.TvCastingApp;
1212
import com.chip.casting.util.GlobalCastingConstants;
1313
import com.matter.casting.ActionSelectorFragment;
14+
import com.matter.casting.ApplicationBasicReadVendorIDExampleFragment;
1415
import com.matter.casting.ConnectionExampleFragment;
1516
import com.matter.casting.ContentLauncherLaunchURLExampleFragment;
1617
import com.matter.casting.DiscoveryExampleFragment;
1718
import com.matter.casting.InitializationExample;
19+
import com.matter.casting.MediaPlaybackSubscribeToCurrentStateExampleFragment;
1820
import com.matter.casting.PreferencesConfigurationManager;
1921
import com.matter.casting.core.CastingPlayer;
2022
import java.util.Random;
@@ -85,6 +87,18 @@ public void handleContentLauncherLaunchURLSelected(CastingPlayer selectedCasting
8587
showFragment(ContentLauncherLaunchURLExampleFragment.newInstance(selectedCastingPlayer));
8688
}
8789

90+
@Override
91+
public void handleApplicationBasicReadVendorIDSelected(CastingPlayer selectedCastingPlayer) {
92+
showFragment(ApplicationBasicReadVendorIDExampleFragment.newInstance(selectedCastingPlayer));
93+
}
94+
95+
@Override
96+
public void handleMediaPlaybackSubscribeToCurrentStateSelected(
97+
CastingPlayer selectedCastingPlayer) {
98+
showFragment(
99+
MediaPlaybackSubscribeToCurrentStateExampleFragment.newInstance(selectedCastingPlayer));
100+
}
101+
88102
@Override
89103
public void handleContentLauncherSelected() {
90104
showFragment(ContentLauncherFragment.newInstance(tvCastingApp));

‎examples/tv-casting-app/android/App/app/src/main/java/com/chip/casting/util/GlobalCastingConstants.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ public class GlobalCastingConstants {
66
public static final int SetupPasscode = 20202021;
77
public static final int Discriminator = 0xF00;
88
public static final boolean ChipCastingSimplified =
9-
false; // set this flag to true to demo simplified casting APIs
9+
true; // set to true, to demo the simplified casting APIs. Otherwise, the older deprecated
10+
// APIs are invoked
1011
}

‎examples/tv-casting-app/android/App/app/src/main/java/com/matter/casting/ActionSelectorFragment.java

+24
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ public class ActionSelectorFragment extends Fragment {
3333
private final CastingPlayer selectedCastingPlayer;
3434

3535
private View.OnClickListener selectContentLauncherButtonClickListener;
36+
private View.OnClickListener selectApplicationBasicButtonClickListener;
37+
private View.OnClickListener selectMediaPlaybackButtonClickListener;
3638
private View.OnClickListener disconnectButtonClickListener;
3739

3840
public ActionSelectorFragment(CastingPlayer selectedCastingPlayer) {
@@ -64,6 +66,16 @@ public View onCreateView(
6466
Log.d(TAG, "handle() called on selectContentLauncherButtonClickListener");
6567
callback.handleContentLauncherLaunchURLSelected(selectedCastingPlayer);
6668
};
69+
this.selectApplicationBasicButtonClickListener =
70+
v -> {
71+
Log.d(TAG, "handle() called on selectApplicationBasicButtonClickListener");
72+
callback.handleApplicationBasicReadVendorIDSelected(selectedCastingPlayer);
73+
};
74+
this.selectMediaPlaybackButtonClickListener =
75+
v -> {
76+
Log.d(TAG, "handle() called on selectMediaPlaybackButtonClickListener");
77+
callback.handleMediaPlaybackSubscribeToCurrentStateSelected(selectedCastingPlayer);
78+
};
6779

6880
this.disconnectButtonClickListener =
6981
v -> {
@@ -82,6 +94,12 @@ public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
8294
getView()
8395
.findViewById(R.id.selectContentLauncherLaunchURLButton)
8496
.setOnClickListener(selectContentLauncherButtonClickListener);
97+
getView()
98+
.findViewById(R.id.selectApplicationBasicReadVendorIDButton)
99+
.setOnClickListener(selectApplicationBasicButtonClickListener);
100+
getView()
101+
.findViewById(R.id.selectMediaPlaybackSubscribeToCurrentStateButton)
102+
.setOnClickListener(selectMediaPlaybackButtonClickListener);
85103

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

112+
/** Notifies listener to trigger transition on selection of Application Basic cluster */
113+
void handleApplicationBasicReadVendorIDSelected(CastingPlayer selectedCastingPlayer);
114+
115+
/** Notifies listener to trigger transition on selection of Media PLayback cluster */
116+
void handleMediaPlaybackSubscribeToCurrentStateSelected(CastingPlayer selectedCastingPlayer);
117+
94118
/** Notifies listener to trigger transition on click of the Disconnect button */
95119
void handleDisconnect();
96120
}

0 commit comments

Comments
 (0)
Please sign in to comment.