Skip to content

Commit 18903b3

Browse files
Add SupportedCluster list to ContentAppPlatform (#33827)
* Add SupportedCluster list to ContentAppPlatform [Problem] The ContentAppPlatform does not know which clusters each ContentApp supports. Currently the ContentApp is queried to get the passcode as long as the AccountLoginDelegate is present whether or not the installed ContentApp has declared support for AccountLogin cluster in its manifest. [Solution] Extend the native ContentApp with a SupportedCluster list. The list is initialized from the Android AppPlatformService whenever an installed ContentApp is discovered and added to the native AppPlatform. This list is used to check if AccountLogin cluster is supported before querying the ContentApp for the passcode. [Test] The feature is tested end-to-end using a native Linux casting-app and and an Android platform-app and content-app. The content-app static_matter_clusters raw asset was manipulated to verify that the clusters are parsed correctly and that the passcode is only retrievable when the AccountLogin cluster is declared. * Restyled by whitespace * Restyled by google-java-format * Restyled by clang-format * ContentApp default constructor * Fix code-lints: check_includes * mapSupportedClusters type fix * Rename feats to features * AccountLogin check in HastargetContentApp * Rename SupportedCluster members to disambiguate * AppPlatformService addContentAppAtEndpoint argument fix * Default SupportedCluster init * Restyled by clang-format * Add AccountLogin cluster to static_matter_clusters * Remove unnecessary namespace specifiers --------- Co-authored-by: Restyled.io <commits@restyled.io>
1 parent 60ae46d commit 18903b3

File tree

13 files changed

+278
-39
lines changed

13 files changed

+278
-39
lines changed

examples/tv-app/android/App/content-app/src/main/res/raw/static_matter_clusters

+3
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@
1919
"features": [
2020
"AS"
2121
]
22+
},
23+
{
24+
"identifier": 1294
2225
}
2326
]
2427
}

examples/tv-app/android/App/platform-app/src/main/java/com/matter/tv/server/service/AppPlatformService.java

+22
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,17 @@
2424
import android.content.IntentFilter;
2525
import android.util.Log;
2626
import androidx.annotation.NonNull;
27+
import com.matter.tv.app.api.SupportedCluster;
2728
import com.matter.tv.server.handlers.ContentAppEndpointManagerImpl;
2829
import com.matter.tv.server.model.ContentApp;
2930
import com.matter.tv.server.receivers.ContentAppDiscoveryService;
3031
import com.matter.tv.server.tvapp.AppPlatform;
32+
import com.matter.tv.server.tvapp.ContentAppSupportedCluster;
3133
import com.matter.tv.server.utils.EndpointsDataStore;
34+
import java.util.Collection;
3235
import java.util.HashMap;
3336
import java.util.Map;
37+
import java.util.stream.Collectors;
3438

3539
/**
3640
* This class facilitates the communication with the ContentAppPlatform. It uses the JNI interface
@@ -168,6 +172,7 @@ public void addContentApp(ContentApp app) {
168172
app.getAppName(),
169173
app.getProductId(),
170174
app.getVersion(),
175+
mapSupportedClusters(app.getSupportedClusters()),
171176
desiredEndpointId,
172177
new ContentAppEndpointManagerImpl(context));
173178
} else {
@@ -178,6 +183,7 @@ public void addContentApp(ContentApp app) {
178183
app.getAppName(),
179184
app.getProductId(),
180185
app.getVersion(),
186+
mapSupportedClusters(app.getSupportedClusters()),
181187
new ContentAppEndpointManagerImpl(context));
182188
}
183189
if (retEndpointId > 0) {
@@ -187,4 +193,20 @@ public void addContentApp(ContentApp app) {
187193
Log.e(TAG, "Could not add content app as endpoint. App Name " + app.getAppName());
188194
}
189195
}
196+
197+
private Collection<ContentAppSupportedCluster> mapSupportedClusters(
198+
Collection<SupportedCluster> supportedClusters) {
199+
return supportedClusters
200+
.stream()
201+
.map(AppPlatformService::mapSupportedCluster)
202+
.collect(Collectors.toList());
203+
}
204+
205+
private static ContentAppSupportedCluster mapSupportedCluster(SupportedCluster cluster) {
206+
return new ContentAppSupportedCluster(
207+
cluster.clusterIdentifier,
208+
cluster.features,
209+
cluster.optionalCommandIdentifiers,
210+
cluster.optionalAttributesIdentifiers);
211+
}
190212
}

examples/tv-app/android/BUILD.gn

+1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ android_library("java") {
122122
"java/src/com/matter/tv/server/tvapp/ChannelProgramResponse.java",
123123
"java/src/com/matter/tv/server/tvapp/Clusters.java",
124124
"java/src/com/matter/tv/server/tvapp/ContentAppEndpointManager.java",
125+
"java/src/com/matter/tv/server/tvapp/ContentAppSupportedCluster.java",
125126
"java/src/com/matter/tv/server/tvapp/ContentLaunchBrandingInformation.java",
126127
"java/src/com/matter/tv/server/tvapp/ContentLaunchEntry.java",
127128
"java/src/com/matter/tv/server/tvapp/ContentLaunchManager.java",

examples/tv-app/android/java/AppImpl.cpp

+32-10
Original file line numberDiff line numberDiff line change
@@ -259,9 +259,26 @@ DataVersion gDataVersions[APP_LIBRARY_SIZE][ArraySize(contentAppClusters)];
259259

260260
EmberAfDeviceType gContentAppDeviceType[] = { { DEVICE_TYPE_CONTENT_APP, 1 } };
261261

262+
std::vector<SupportedCluster> make_default_supported_clusters()
263+
{
264+
return std::vector<ContentApp::SupportedCluster>{ { Descriptor::Id }, { ApplicationBasic::Id },
265+
{ KeypadInput::Id }, { ApplicationLauncher::Id },
266+
{ AccountLogin::Id }, { ContentLauncher::Id },
267+
{ TargetNavigator::Id }, { Channel::Id } };
268+
}
269+
262270
} // anonymous namespace
263271

264-
ContentAppFactoryImpl::ContentAppFactoryImpl() {}
272+
ContentAppFactoryImpl::ContentAppFactoryImpl() :
273+
mContentApps{ new ContentAppImpl("Vendor1", 1, "exampleid", 11, "Version1", "20202021", make_default_supported_clusters(),
274+
nullptr, nullptr),
275+
new ContentAppImpl("Vendor2", 65521, "exampleString", 32768, "Version2", "20202021",
276+
make_default_supported_clusters(), nullptr, nullptr),
277+
new ContentAppImpl("Vendor3", 9050, "App3", 22, "Version3", "20202021", make_default_supported_clusters(),
278+
nullptr, nullptr),
279+
new ContentAppImpl("TestSuiteVendor", 1111, "applicationId", 22, "v2", "20202021",
280+
make_default_supported_clusters(), nullptr, nullptr) }
281+
{}
265282

266283
uint16_t ContentAppFactoryImpl::GetPlatformCatalogVendorId()
267284
{
@@ -339,11 +356,12 @@ ContentApp * ContentAppFactoryImpl::LoadContentApp(const CatalogVendorApp & vend
339356
}
340357

341358
EndpointId ContentAppFactoryImpl::AddContentApp(const char * szVendorName, uint16_t vendorId, const char * szApplicationName,
342-
uint16_t productId, const char * szApplicationVersion, jobject manager)
359+
uint16_t productId, const char * szApplicationVersion,
360+
std::vector<SupportedCluster> supportedClusters, jobject manager)
343361
{
344362
DataVersion * dataVersionBuf = new DataVersion[ArraySize(contentAppClusters)];
345363
ContentAppImpl * app = new ContentAppImpl(szVendorName, vendorId, szApplicationName, productId, szApplicationVersion, "",
346-
mAttributeDelegate, mCommandDelegate);
364+
std::move(supportedClusters), mAttributeDelegate, mCommandDelegate);
347365
EndpointId epId = ContentAppPlatform::GetInstance().AddContentApp(
348366
app, &contentAppEndpoint, Span<DataVersion>(dataVersionBuf, ArraySize(contentAppClusters)),
349367
Span<const EmberAfDeviceType>(gContentAppDeviceType));
@@ -355,12 +373,13 @@ EndpointId ContentAppFactoryImpl::AddContentApp(const char * szVendorName, uint1
355373
}
356374

357375
EndpointId ContentAppFactoryImpl::AddContentApp(const char * szVendorName, uint16_t vendorId, const char * szApplicationName,
358-
uint16_t productId, const char * szApplicationVersion, jobject manager,
359-
EndpointId desiredEndpointId)
376+
uint16_t productId, const char * szApplicationVersion,
377+
std::vector<SupportedCluster> supportedClusters, EndpointId desiredEndpointId,
378+
jobject manager)
360379
{
361380
DataVersion * dataVersionBuf = new DataVersion[ArraySize(contentAppClusters)];
362381
ContentAppImpl * app = new ContentAppImpl(szVendorName, vendorId, szApplicationName, productId, szApplicationVersion, "",
363-
mAttributeDelegate, mCommandDelegate);
382+
std::move(supportedClusters), mAttributeDelegate, mCommandDelegate);
364383
EndpointId epId = ContentAppPlatform::GetInstance().AddContentApp(
365384
app, &contentAppEndpoint, Span<DataVersion>(dataVersionBuf, ArraySize(contentAppClusters)),
366385
Span<const EmberAfDeviceType>(gContentAppDeviceType), desiredEndpointId);
@@ -480,21 +499,24 @@ CHIP_ERROR InitVideoPlayerPlatform(jobject contentAppEndpointManager)
480499
}
481500

482501
EndpointId AddContentApp(const char * szVendorName, uint16_t vendorId, const char * szApplicationName, uint16_t productId,
483-
const char * szApplicationVersion, jobject manager)
502+
const char * szApplicationVersion, std::vector<SupportedCluster> supportedClusters, jobject manager)
484503
{
485504
#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
486505
ChipLogProgress(DeviceLayer, "AppImpl: AddContentApp vendorId=%d applicationName=%s ", vendorId, szApplicationName);
487-
return gFactory.AddContentApp(szVendorName, vendorId, szApplicationName, productId, szApplicationVersion, manager);
506+
return gFactory.AddContentApp(szVendorName, vendorId, szApplicationName, productId, szApplicationVersion,
507+
std::move(supportedClusters), manager);
488508
#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
489509
return kInvalidEndpointId;
490510
}
491511

492512
EndpointId AddContentApp(const char * szVendorName, uint16_t vendorId, const char * szApplicationName, uint16_t productId,
493-
const char * szApplicationVersion, EndpointId endpointId, jobject manager)
513+
const char * szApplicationVersion, std::vector<SupportedCluster> supportedClusters, EndpointId endpointId,
514+
jobject manager)
494515
{
495516
#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
496517
ChipLogProgress(DeviceLayer, "AppImpl: AddContentApp vendorId=%d applicationName=%s ", vendorId, szApplicationName);
497-
return gFactory.AddContentApp(szVendorName, vendorId, szApplicationName, productId, szApplicationVersion, manager, endpointId);
518+
return gFactory.AddContentApp(szVendorName, vendorId, szApplicationName, productId, szApplicationVersion,
519+
std::move(supportedClusters), endpointId, manager);
498520
#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
499521
return kInvalidEndpointId;
500522
}

examples/tv-app/android/java/AppImpl.h

+15-13
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include <lib/support/JniReferences.h>
3232
#include <stdbool.h>
3333
#include <stdint.h>
34+
#include <vector>
3435

3536
#include "../include/account-login/AccountLoginManager.h"
3637
#include "../include/application-basic/ApplicationBasicManager.h"
@@ -56,9 +57,12 @@
5657

5758
CHIP_ERROR InitVideoPlayerPlatform(jobject contentAppEndpointManager);
5859
EndpointId AddContentApp(const char * szVendorName, uint16_t vendorId, const char * szApplicationName, uint16_t productId,
59-
const char * szApplicationVersion, jobject manager);
60+
const char * szApplicationVersion,
61+
std::vector<chip::AppPlatform::ContentApp::SupportedCluster> supportedClusters, jobject manager);
6062
EndpointId AddContentApp(const char * szVendorName, uint16_t vendorId, const char * szApplicationName, uint16_t productId,
61-
const char * szApplicationVersion, EndpointId endpointId, jobject manager);
63+
const char * szApplicationVersion,
64+
std::vector<chip::AppPlatform::ContentApp::SupportedCluster> supportedClusters, EndpointId endpointId,
65+
jobject manager);
6266
EndpointId RemoveContentApp(EndpointId epId);
6367
void ReportAttributeChange(EndpointId epId, chip::ClusterId clusterId, chip::AttributeId attributeId);
6468

@@ -81,6 +85,7 @@ using TargetNavigatorDelegate = app::Clusters::TargetNavigator::Delegate;
8185
using SupportedProtocolsBitmap = app::Clusters::ContentLauncher::SupportedProtocolsBitmap;
8286
using ContentAppAttributeDelegate = chip::AppPlatform::ContentAppAttributeDelegate;
8387
using ContentAppCommandDelegate = chip::AppPlatform::ContentAppCommandDelegate;
88+
using SupportedCluster = chip::AppPlatform::ContentApp::SupportedCluster;
8489

8590
static const int kCatalogVendorId = CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID;
8691

@@ -91,8 +96,9 @@ class DLL_EXPORT ContentAppImpl : public ContentApp
9196
{
9297
public:
9398
ContentAppImpl(const char * szVendorName, uint16_t vendorId, const char * szApplicationName, uint16_t productId,
94-
const char * szApplicationVersion, const char * setupPIN, ContentAppAttributeDelegate * attributeDelegate,
95-
ContentAppCommandDelegate * commandDelegate) :
99+
const char * szApplicationVersion, const char * setupPIN, std::vector<SupportedCluster> supportedClusters,
100+
ContentAppAttributeDelegate * attributeDelegate, ContentAppCommandDelegate * commandDelegate) :
101+
ContentApp{ supportedClusters },
96102
mApplicationBasicDelegate(kCatalogVendorId, BuildAppId(vendorId), szVendorName, vendorId, szApplicationName, productId,
97103
szApplicationVersion),
98104
mAccountLoginDelegate(commandDelegate, setupPIN),
@@ -160,10 +166,11 @@ class DLL_EXPORT ContentAppFactoryImpl : public ContentAppFactory
160166
ContentApp * LoadContentApp(const CatalogVendorApp & vendorApp) override;
161167

162168
EndpointId AddContentApp(const char * szVendorName, uint16_t vendorId, const char * szApplicationName, uint16_t productId,
163-
const char * szApplicationVersion, jobject manager);
169+
const char * szApplicationVersion, std::vector<SupportedCluster> supportedClusters, jobject manager);
164170

165171
EndpointId AddContentApp(const char * szVendorName, uint16_t vendorId, const char * szApplicationName, uint16_t productId,
166-
const char * szApplicationVersion, jobject manager, EndpointId desiredEndpointId);
172+
const char * szApplicationVersion, std::vector<SupportedCluster> supportedClusters,
173+
EndpointId desiredEndpointId, jobject manager);
167174

168175
EndpointId RemoveContentApp(EndpointId epId);
169176

@@ -192,14 +199,9 @@ class DLL_EXPORT ContentAppFactoryImpl : public ContentAppFactory
192199
void setContentAppCommandDelegate(ContentAppCommandDelegate * commandDelegate);
193200

194201
protected:
195-
std::vector<ContentAppImpl *> mContentApps{
196-
new ContentAppImpl("Vendor1", 1, "exampleid", 11, "Version1", "20202021", nullptr, nullptr),
197-
new ContentAppImpl("Vendor2", 65521, "exampleString", 32768, "Version2", "20202021", nullptr, nullptr),
198-
new ContentAppImpl("Vendor3", 9050, "App3", 22, "Version3", "20202021", nullptr, nullptr),
199-
new ContentAppImpl("TestSuiteVendor", 1111, "applicationId", 22, "v2", "20202021", nullptr, nullptr)
200-
};
202+
// TODO: Update to use unique_ptr instead of raw pointers
203+
std::vector<ContentAppImpl *> mContentApps;
201204
std::vector<DataVersion *> mDataVersions{};
202-
203205
std::vector<uint16_t> mAdminVendorIds{};
204206

205207
private:

0 commit comments

Comments
 (0)