AppImpl.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517
  1. /*
  2. *
  3. * Copyright (c) 2021 Project CHIP Authors
  4. *
  5. * Licensed under the Apache License, Version 2.0 (the "License");
  6. * you may not use this file except in compliance with the License.
  7. * You may obtain a copy of the License at
  8. *
  9. * http://www.apache.org/licenses/LICENSE-2.0
  10. *
  11. * Unless required by applicable law or agreed to in writing, software
  12. * distributed under the License is distributed on an "AS IS" BASIS,
  13. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14. * See the License for the specific language governing permissions and
  15. * limitations under the License.
  16. */
  17. /**
  18. * @file Contains Implementation of the ContentApp and the ContentAppPlatform.
  19. */
  20. #include "AppImpl.h"
  21. #include "ContentAppAttributeDelegate.h"
  22. #include "ContentAppCommandDelegate.h"
  23. #include <app-common/zap-generated/ids/Attributes.h>
  24. #include <app-common/zap-generated/ids/Clusters.h>
  25. #include <app/CommandHandler.h>
  26. #include <app/InteractionModelEngine.h>
  27. #include <app/reporting/reporting.h>
  28. #include <app/server/Dnssd.h>
  29. #include <app/server/Server.h>
  30. #include <app/util/af.h>
  31. #include <cstdio>
  32. #include <inttypes.h>
  33. #include <jni.h>
  34. #include <lib/core/CHIPCore.h>
  35. #include <lib/shell/Commands.h>
  36. #include <lib/shell/Engine.h>
  37. #include <lib/shell/commands/Help.h>
  38. #include <lib/support/CHIPArgParser.hpp>
  39. #include <lib/support/CHIPMem.h>
  40. #include <lib/support/CodeUtils.h>
  41. #include <lib/support/ZclString.h>
  42. #include <platform/CHIPDeviceLayer.h>
  43. #include <platform/DeviceInstanceInfoProvider.h>
  44. using namespace chip;
  45. using namespace chip::app::Clusters;
  46. using namespace chip::AppPlatform;
  47. using namespace chip::DeviceLayer;
  48. #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
  49. ContentAppFactoryImpl gFactory;
  50. ContentAppFactoryImpl * GetContentAppFactoryImpl()
  51. {
  52. return &gFactory;
  53. }
  54. namespace chip {
  55. namespace AppPlatform {
  56. // BEGIN DYNAMIC ENDPOINTS
  57. // =================================================================================
  58. static const int kNameSize = 32;
  59. // Current ZCL implementation of Struct uses a max-size array of 254 bytes
  60. static const int kDescriptorAttributeArraySize = 254;
  61. // Device types for dynamic endpoints: TODO Need a generated file from ZAP to define these!
  62. // (taken from chip-devices.xml)
  63. #define DEVICE_TYPE_CONTENT_APP 0x0024
  64. // ---------------------------------------------------------------------------
  65. //
  66. // CONTENT APP ENDPOINT: contains the following clusters:
  67. // - Descriptor
  68. // - Application Basic
  69. // - Keypad Input
  70. // - Application Launcher
  71. // - Account Login
  72. // - Content Launcher
  73. // - Target Navigator
  74. // - Channel
  75. // Declare Descriptor cluster attributes
  76. DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(descriptorAttrs)
  77. DECLARE_DYNAMIC_ATTRIBUTE(Descriptor::Attributes::DeviceTypeList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* device list */
  78. DECLARE_DYNAMIC_ATTRIBUTE(Descriptor::Attributes::ServerList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* server list */
  79. DECLARE_DYNAMIC_ATTRIBUTE(Descriptor::Attributes::ClientList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* client list */
  80. DECLARE_DYNAMIC_ATTRIBUTE(Descriptor::Attributes::PartsList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* parts list */
  81. DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
  82. // Declare Application Basic information cluster attributes
  83. DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(applicationBasicAttrs)
  84. DECLARE_DYNAMIC_ATTRIBUTE(ApplicationBasic::Attributes::VendorName::Id, CHAR_STRING, kNameSize, 0), /* VendorName */
  85. DECLARE_DYNAMIC_ATTRIBUTE(ApplicationBasic::Attributes::VendorID::Id, INT16U, 1, 0), /* VendorID */
  86. DECLARE_DYNAMIC_ATTRIBUTE(ApplicationBasic::Attributes::ApplicationName::Id, CHAR_STRING, kNameSize, 0), /* ApplicationName */
  87. DECLARE_DYNAMIC_ATTRIBUTE(ApplicationBasic::Attributes::ProductID::Id, INT16U, 1, 0), /* ProductID */
  88. DECLARE_DYNAMIC_ATTRIBUTE(ApplicationBasic::Attributes::Status::Id, INT8U, 1, 0), /* ApplicationStatus */
  89. DECLARE_DYNAMIC_ATTRIBUTE(ApplicationBasic::Attributes::ApplicationVersion::Id, CHAR_STRING, kNameSize,
  90. 0), /* ApplicationVersion */
  91. DECLARE_DYNAMIC_ATTRIBUTE(ApplicationBasic::Attributes::AllowedVendorList::Id, ARRAY, kDescriptorAttributeArraySize,
  92. 0), /* AllowedVendorList */
  93. DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
  94. // Declare Keypad Input cluster attributes
  95. DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(keypadInputAttrs)
  96. DECLARE_DYNAMIC_ATTRIBUTE(KeypadInput::Attributes::FeatureMap::Id, BITMAP32, 4, 0), /* FeatureMap */
  97. DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
  98. // Declare Application Launcher cluster attributes
  99. // NOTE: Does not make sense for content app to be able to set the AP feature flag
  100. DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(applicationLauncherAttrs)
  101. DECLARE_DYNAMIC_ATTRIBUTE(ApplicationLauncher::Attributes::CatalogList::Id, ARRAY, kDescriptorAttributeArraySize,
  102. 0), /* catalog list */
  103. DECLARE_DYNAMIC_ATTRIBUTE(ApplicationLauncher::Attributes::CurrentApp::Id, STRUCT, 1, 0), /* current app */
  104. DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
  105. // Declare Account Login cluster attributes
  106. DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(accountLoginAttrs)
  107. DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
  108. // Declare Content Launcher cluster attributes
  109. DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(contentLauncherAttrs)
  110. DECLARE_DYNAMIC_ATTRIBUTE(ContentLauncher::Attributes::AcceptHeader::Id, ARRAY, kDescriptorAttributeArraySize,
  111. 0), /* accept header list */
  112. DECLARE_DYNAMIC_ATTRIBUTE(ContentLauncher::Attributes::SupportedStreamingProtocols::Id, BITMAP32, 1,
  113. 0), /* streaming protocols */
  114. DECLARE_DYNAMIC_ATTRIBUTE(ContentLauncher::Attributes::FeatureMap::Id, BITMAP32, 4, 0), /* FeatureMap */
  115. DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
  116. // Declare Media Playback cluster attributes
  117. DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(mediaPlaybackAttrs)
  118. DECLARE_DYNAMIC_ATTRIBUTE(MediaPlayback::Attributes::CurrentState::Id, ENUM8, 1, 0), /* current state */
  119. DECLARE_DYNAMIC_ATTRIBUTE(MediaPlayback::Attributes::StartTime::Id, EPOCH_US, 1, 0), /* start time */
  120. DECLARE_DYNAMIC_ATTRIBUTE(MediaPlayback::Attributes::Duration::Id, INT64U, 1, 0), /* duration */
  121. DECLARE_DYNAMIC_ATTRIBUTE(MediaPlayback::Attributes::SampledPosition::Id, STRUCT, 1, 0), /* SampledPosition */
  122. DECLARE_DYNAMIC_ATTRIBUTE(MediaPlayback::Attributes::PlaybackSpeed::Id, SINGLE, 1, 0), /* playback speed */
  123. DECLARE_DYNAMIC_ATTRIBUTE(MediaPlayback::Attributes::SeekRangeEnd::Id, INT64U, 1, 0), /* seek range end */
  124. DECLARE_DYNAMIC_ATTRIBUTE(MediaPlayback::Attributes::SeekRangeStart::Id, INT64U, 1, 0), /* seek range start */
  125. DECLARE_DYNAMIC_ATTRIBUTE(MediaPlayback::Attributes::FeatureMap::Id, BITMAP32, 4, 0), /* FeatureMap */
  126. DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
  127. // Declare Target Navigator cluster attributes
  128. DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(targetNavigatorAttrs)
  129. DECLARE_DYNAMIC_ATTRIBUTE(TargetNavigator::Attributes::TargetList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* target list */
  130. DECLARE_DYNAMIC_ATTRIBUTE(TargetNavigator::Attributes::CurrentTarget::Id, INT8U, 1, 0), /* current target */
  131. DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
  132. // Declare Channel cluster attributes
  133. DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(channelAttrs)
  134. DECLARE_DYNAMIC_ATTRIBUTE(Channel::Attributes::ChannelList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* channel list */
  135. DECLARE_DYNAMIC_ATTRIBUTE(Channel::Attributes::Lineup::Id, STRUCT, 1, 0), /* lineup */
  136. DECLARE_DYNAMIC_ATTRIBUTE(Channel::Attributes::CurrentChannel::Id, STRUCT, 1, 0), /* current channel */
  137. DECLARE_DYNAMIC_ATTRIBUTE(Channel::Attributes::FeatureMap::Id, BITMAP32, 4, 0), /* FeatureMap */
  138. DECLARE_DYNAMIC_ATTRIBUTE_LIST_END();
  139. constexpr CommandId keypadInputIncomingCommands[] = {
  140. app::Clusters::KeypadInput::Commands::SendKey::Id,
  141. kInvalidCommandId,
  142. };
  143. constexpr CommandId keypadInputOutgoingCommands[] = {
  144. app::Clusters::KeypadInput::Commands::SendKeyResponse::Id,
  145. kInvalidCommandId,
  146. };
  147. constexpr CommandId applicationLauncherIncomingCommands[] = {
  148. app::Clusters::ApplicationLauncher::Commands::LaunchApp::Id,
  149. app::Clusters::ApplicationLauncher::Commands::StopApp::Id,
  150. app::Clusters::ApplicationLauncher::Commands::HideApp::Id,
  151. kInvalidCommandId,
  152. };
  153. constexpr CommandId applicationLauncherOutgoingCommands[] = {
  154. app::Clusters::ApplicationLauncher::Commands::LauncherResponse::Id,
  155. kInvalidCommandId,
  156. };
  157. constexpr CommandId accountLoginIncomingCommands[] = {
  158. app::Clusters::AccountLogin::Commands::GetSetupPIN::Id,
  159. app::Clusters::AccountLogin::Commands::Login::Id,
  160. app::Clusters::AccountLogin::Commands::Logout::Id,
  161. kInvalidCommandId,
  162. };
  163. constexpr CommandId accountLoginOutgoingCommands[] = {
  164. app::Clusters::AccountLogin::Commands::GetSetupPINResponse::Id,
  165. kInvalidCommandId,
  166. };
  167. // TODO: Sort out when the optional commands here should be listed.
  168. constexpr CommandId contentLauncherIncomingCommands[] = {
  169. app::Clusters::ContentLauncher::Commands::LaunchContent::Id,
  170. app::Clusters::ContentLauncher::Commands::LaunchURL::Id,
  171. kInvalidCommandId,
  172. };
  173. constexpr CommandId contentLauncherOutgoingCommands[] = {
  174. app::Clusters::ContentLauncher::Commands::LauncherResponse::Id,
  175. kInvalidCommandId,
  176. };
  177. // TODO: Sort out when the optional commands here should be listed.
  178. constexpr CommandId mediaPlaybackIncomingCommands[] = {
  179. app::Clusters::MediaPlayback::Commands::Play::Id, app::Clusters::MediaPlayback::Commands::Pause::Id,
  180. app::Clusters::MediaPlayback::Commands::Stop::Id, app::Clusters::MediaPlayback::Commands::StartOver::Id,
  181. app::Clusters::MediaPlayback::Commands::Previous::Id, app::Clusters::MediaPlayback::Commands::Next::Id,
  182. app::Clusters::MediaPlayback::Commands::Rewind::Id, app::Clusters::MediaPlayback::Commands::FastForward::Id,
  183. app::Clusters::MediaPlayback::Commands::SkipForward::Id, app::Clusters::MediaPlayback::Commands::SkipBackward::Id,
  184. app::Clusters::MediaPlayback::Commands::Seek::Id, kInvalidCommandId,
  185. };
  186. constexpr CommandId mediaPlaybackOutgoingCommands[] = {
  187. app::Clusters::MediaPlayback::Commands::PlaybackResponse::Id,
  188. kInvalidCommandId,
  189. };
  190. constexpr CommandId targetNavigatorIncomingCommands[] = {
  191. app::Clusters::TargetNavigator::Commands::NavigateTarget::Id,
  192. kInvalidCommandId,
  193. };
  194. constexpr CommandId targetNavigatorOutgoingCommands[] = {
  195. app::Clusters::TargetNavigator::Commands::NavigateTargetResponse::Id,
  196. kInvalidCommandId,
  197. };
  198. // TODO: Sort out when the optional commands here should be listed.
  199. constexpr CommandId channelIncomingCommands[] = {
  200. app::Clusters::Channel::Commands::ChangeChannel::Id,
  201. app::Clusters::Channel::Commands::ChangeChannelByNumber::Id,
  202. app::Clusters::Channel::Commands::SkipChannel::Id,
  203. kInvalidCommandId,
  204. };
  205. constexpr CommandId channelOutgoingCommands[] = {
  206. app::Clusters::Channel::Commands::ChangeChannelResponse::Id,
  207. kInvalidCommandId,
  208. };
  209. // Declare Cluster List for Content App endpoint
  210. DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(contentAppClusters)
  211. DECLARE_DYNAMIC_CLUSTER(app::Clusters::Descriptor::Id, descriptorAttrs, nullptr, nullptr),
  212. DECLARE_DYNAMIC_CLUSTER(app::Clusters::ApplicationBasic::Id, applicationBasicAttrs, nullptr, nullptr),
  213. DECLARE_DYNAMIC_CLUSTER(app::Clusters::KeypadInput::Id, keypadInputAttrs, keypadInputIncomingCommands,
  214. keypadInputOutgoingCommands),
  215. DECLARE_DYNAMIC_CLUSTER(app::Clusters::ApplicationLauncher::Id, applicationLauncherAttrs, applicationLauncherIncomingCommands,
  216. applicationLauncherOutgoingCommands),
  217. DECLARE_DYNAMIC_CLUSTER(app::Clusters::AccountLogin::Id, accountLoginAttrs, accountLoginIncomingCommands,
  218. accountLoginOutgoingCommands),
  219. DECLARE_DYNAMIC_CLUSTER(app::Clusters::ContentLauncher::Id, contentLauncherAttrs, contentLauncherIncomingCommands,
  220. contentLauncherOutgoingCommands),
  221. DECLARE_DYNAMIC_CLUSTER(app::Clusters::MediaPlayback::Id, mediaPlaybackAttrs, mediaPlaybackIncomingCommands,
  222. mediaPlaybackOutgoingCommands),
  223. DECLARE_DYNAMIC_CLUSTER(app::Clusters::TargetNavigator::Id, targetNavigatorAttrs, targetNavigatorIncomingCommands,
  224. targetNavigatorOutgoingCommands),
  225. DECLARE_DYNAMIC_CLUSTER(app::Clusters::Channel::Id, channelAttrs, channelIncomingCommands, channelOutgoingCommands),
  226. DECLARE_DYNAMIC_CLUSTER_LIST_END;
  227. // Declare Content App endpoint
  228. DECLARE_DYNAMIC_ENDPOINT(contentAppEndpoint, contentAppClusters);
  229. namespace {
  230. DataVersion gDataVersions[APP_LIBRARY_SIZE][ArraySize(contentAppClusters)];
  231. EmberAfDeviceType gContentAppDeviceType[] = { { DEVICE_TYPE_CONTENT_APP, 1 } };
  232. } // anonymous namespace
  233. ContentAppFactoryImpl::ContentAppFactoryImpl() {}
  234. uint16_t ContentAppFactoryImpl::GetPlatformCatalogVendorId()
  235. {
  236. return kCatalogVendorId;
  237. }
  238. void ContentAppFactoryImpl::setContentAppAttributeDelegate(ContentAppAttributeDelegate * attributeDelegate)
  239. {
  240. mAttributeDelegate = attributeDelegate;
  241. }
  242. void ContentAppFactoryImpl::setContentAppCommandDelegate(ContentAppCommandDelegate * commandDelegate)
  243. {
  244. mCommandDelegate = commandDelegate;
  245. }
  246. CHIP_ERROR ContentAppFactoryImpl::LookupCatalogVendorApp(uint16_t vendorId, uint16_t productId, CatalogVendorApp * destinationApp)
  247. {
  248. std::string appId = BuildAppId(vendorId);
  249. destinationApp->catalogVendorId = GetPlatformCatalogVendorId();
  250. Platform::CopyString(destinationApp->applicationId, sizeof(destinationApp->applicationId), appId.c_str());
  251. return CHIP_NO_ERROR;
  252. }
  253. CHIP_ERROR ContentAppFactoryImpl::ConvertToPlatformCatalogVendorApp(const CatalogVendorApp & sourceApp,
  254. CatalogVendorApp * destinationApp)
  255. {
  256. destinationApp->catalogVendorId = GetPlatformCatalogVendorId();
  257. std::string appId(sourceApp.applicationId);
  258. if (appId == "applicationId")
  259. {
  260. // regression test case passes "applicationId", map this to our test suite app
  261. Platform::CopyString(destinationApp->applicationId, sizeof(destinationApp->applicationId), "1111");
  262. }
  263. else if (appId == "exampleid")
  264. {
  265. // cert test case passes "exampleid", map this to our test suite app
  266. Platform::CopyString(destinationApp->applicationId, sizeof(destinationApp->applicationId), "1");
  267. }
  268. else if (appId == "exampleString")
  269. {
  270. // cert test case passes "exampleString", map this to our test suite app
  271. Platform::CopyString(destinationApp->applicationId, sizeof(destinationApp->applicationId), "65521");
  272. }
  273. else
  274. {
  275. // for now, just return the applicationId passed in
  276. Platform::CopyString(destinationApp->applicationId, sizeof(destinationApp->applicationId), sourceApp.applicationId);
  277. }
  278. return CHIP_NO_ERROR;
  279. }
  280. ContentApp * ContentAppFactoryImpl::LoadContentApp(const CatalogVendorApp & vendorApp)
  281. {
  282. ChipLogProgress(DeviceLayer, "ContentAppFactoryImpl: LoadContentAppByAppId catalogVendorId=%d applicationId=%s ",
  283. vendorApp.catalogVendorId, vendorApp.applicationId);
  284. for (size_t i = 0; i < mContentApps.size(); ++i)
  285. {
  286. auto & app = mContentApps.at(i);
  287. ChipLogProgress(DeviceLayer, " Looking next=%s ", app->GetApplicationBasicDelegate()->GetCatalogVendorApp()->applicationId);
  288. if (app->GetApplicationBasicDelegate()->GetCatalogVendorApp()->Matches(vendorApp))
  289. {
  290. ContentAppPlatform::GetInstance().AddContentApp(app, &contentAppEndpoint, Span<DataVersion>(gDataVersions[i]),
  291. Span<const EmberAfDeviceType>(gContentAppDeviceType));
  292. return app;
  293. }
  294. }
  295. ChipLogProgress(DeviceLayer, "LoadContentAppByAppId NOT FOUND catalogVendorId=%d applicationId=%s ", vendorApp.catalogVendorId,
  296. vendorApp.applicationId);
  297. return nullptr;
  298. }
  299. EndpointId ContentAppFactoryImpl::AddContentApp(const char * szVendorName, uint16_t vendorId, const char * szApplicationName,
  300. uint16_t productId, const char * szApplicationVersion, jobject manager)
  301. {
  302. DataVersion * dataVersionBuf = new DataVersion[ArraySize(contentAppClusters)];
  303. ContentAppImpl * app = new ContentAppImpl(szVendorName, vendorId, szApplicationName, productId, szApplicationVersion, "",
  304. mAttributeDelegate, mCommandDelegate);
  305. EndpointId epId = ContentAppPlatform::GetInstance().AddContentApp(
  306. app, &contentAppEndpoint, Span<DataVersion>(dataVersionBuf, ArraySize(contentAppClusters)),
  307. Span<const EmberAfDeviceType>(gContentAppDeviceType));
  308. ChipLogProgress(DeviceLayer, "ContentAppFactoryImpl AddContentApp endpoint returned %d. Endpoint set %d", epId,
  309. app->GetEndpointId());
  310. mContentApps.push_back(app);
  311. mDataVersions.push_back(dataVersionBuf);
  312. return epId;
  313. }
  314. EndpointId ContentAppFactoryImpl::AddContentApp(const char * szVendorName, uint16_t vendorId, const char * szApplicationName,
  315. uint16_t productId, const char * szApplicationVersion, jobject manager,
  316. EndpointId desiredEndpointId)
  317. {
  318. DataVersion * dataVersionBuf = new DataVersion[ArraySize(contentAppClusters)];
  319. ContentAppImpl * app = new ContentAppImpl(szVendorName, vendorId, szApplicationName, productId, szApplicationVersion, "",
  320. mAttributeDelegate, mCommandDelegate);
  321. EndpointId epId = ContentAppPlatform::GetInstance().AddContentApp(
  322. app, &contentAppEndpoint, Span<DataVersion>(dataVersionBuf, ArraySize(contentAppClusters)),
  323. Span<const EmberAfDeviceType>(gContentAppDeviceType), desiredEndpointId);
  324. ChipLogProgress(DeviceLayer, "ContentAppFactoryImpl AddContentApp endpoint returned %d. Endpoint set %d", epId,
  325. app->GetEndpointId());
  326. mContentApps.push_back(app);
  327. mDataVersions.push_back(dataVersionBuf);
  328. return epId;
  329. }
  330. EndpointId ContentAppFactoryImpl::RemoveContentApp(EndpointId epId)
  331. {
  332. for (size_t i = 0; i < mContentApps.size(); ++i)
  333. {
  334. auto & app = mContentApps.at(i);
  335. if (app->GetEndpointId() == epId)
  336. {
  337. ChipLogProgress(DeviceLayer, "ContentAppFactoryImpl RemoveContentApp endpointId %d", epId);
  338. EndpointId removedEndpointID = ContentAppPlatform::GetInstance().RemoveContentApp(app);
  339. // Only remove the app from the set of content apps if they were dynamically added and not part of the static list of
  340. // apps
  341. if (removedEndpointID != 0 && i > APP_LIBRARY_SIZE)
  342. {
  343. mContentApps.erase(mContentApps.begin() + static_cast<int>(i));
  344. DataVersion * dataVersionBuf = mDataVersions.at(i - APP_LIBRARY_SIZE);
  345. mDataVersions.erase(mDataVersions.begin() + static_cast<int>(i - APP_LIBRARY_SIZE));
  346. // deallocate memory for objects that were created when adding the content app dynamically.
  347. delete[] dataVersionBuf;
  348. delete app;
  349. }
  350. return removedEndpointID;
  351. }
  352. }
  353. return kInvalidEndpointId;
  354. }
  355. void ContentAppFactoryImpl::AddAdminVendorId(uint16_t vendorId)
  356. {
  357. mAdminVendorIds.push_back(vendorId);
  358. }
  359. Access::Privilege ContentAppFactoryImpl::GetVendorPrivilege(uint16_t vendorId)
  360. {
  361. for (size_t i = 0; i < mAdminVendorIds.size(); ++i)
  362. {
  363. auto & vendor = mAdminVendorIds.at(i);
  364. if (vendorId == vendor)
  365. {
  366. return Access::Privilege::kAdminister;
  367. }
  368. }
  369. return Access::Privilege::kOperate;
  370. }
  371. std::list<ClusterId> ContentAppFactoryImpl::GetAllowedClusterListForStaticEndpoint(EndpointId endpointId, uint16_t vendorId,
  372. uint16_t productId)
  373. {
  374. if (endpointId == kLocalVideoPlayerEndpointId)
  375. {
  376. if (GetVendorPrivilege(vendorId) == Access::Privilege::kAdminister)
  377. {
  378. ChipLogProgress(DeviceLayer,
  379. "ContentAppFactoryImpl GetAllowedClusterListForStaticEndpoint priviledged vendor accessible clusters "
  380. "being returned.");
  381. return { chip::app::Clusters::Descriptor::Id, chip::app::Clusters::OnOff::Id,
  382. chip::app::Clusters::WakeOnLan::Id, chip::app::Clusters::MediaPlayback::Id,
  383. chip::app::Clusters::LowPower::Id, chip::app::Clusters::KeypadInput::Id,
  384. chip::app::Clusters::ContentLauncher::Id, chip::app::Clusters::AudioOutput::Id,
  385. chip::app::Clusters::ApplicationLauncher::Id };
  386. }
  387. ChipLogProgress(
  388. DeviceLayer,
  389. "ContentAppFactoryImpl GetAllowedClusterListForStaticEndpoint operator vendor accessible clusters being returned.");
  390. return { chip::app::Clusters::Descriptor::Id, chip::app::Clusters::OnOff::Id,
  391. chip::app::Clusters::WakeOnLan::Id, chip::app::Clusters::MediaPlayback::Id,
  392. chip::app::Clusters::LowPower::Id, chip::app::Clusters::KeypadInput::Id,
  393. chip::app::Clusters::ContentLauncher::Id, chip::app::Clusters::AudioOutput::Id };
  394. }
  395. return {};
  396. }
  397. } // namespace AppPlatform
  398. } // namespace chip
  399. #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
  400. CHIP_ERROR InitVideoPlayerPlatform(jobject contentAppEndpointManager)
  401. {
  402. #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
  403. ContentAppPlatform::GetInstance().SetupAppPlatform();
  404. ContentAppPlatform::GetInstance().SetContentAppFactory(&gFactory);
  405. gFactory.setContentAppAttributeDelegate(new ContentAppAttributeDelegate(contentAppEndpointManager));
  406. gFactory.setContentAppCommandDelegate(new ContentAppCommandDelegate(contentAppEndpointManager));
  407. ChipLogProgress(AppServer, "Starting registration of command handler delegates");
  408. for (size_t i = 0; i < ArraySize(contentAppClusters); i++)
  409. {
  410. ContentAppCommandDelegate * delegate =
  411. new ContentAppCommandDelegate(contentAppEndpointManager, contentAppClusters[i].clusterId);
  412. chip::app::InteractionModelEngine::GetInstance()->RegisterCommandHandler(delegate);
  413. ChipLogProgress(AppServer, "Registered command handler delegate for cluster %d", contentAppClusters[i].clusterId);
  414. }
  415. #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
  416. // Disable last fixed endpoint, which is used as a placeholder for all of the
  417. // supported clusters so that ZAP will generated the requisite code.
  418. ChipLogDetail(DeviceLayer, "TV App: Disabling Fixed Content App Endpoints");
  419. emberAfEndpointEnableDisable(3, false);
  420. return CHIP_NO_ERROR;
  421. }
  422. EndpointId AddContentApp(const char * szVendorName, uint16_t vendorId, const char * szApplicationName, uint16_t productId,
  423. const char * szApplicationVersion, jobject manager)
  424. {
  425. #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
  426. ChipLogProgress(DeviceLayer, "AppImpl: AddContentApp vendorId=%d applicationName=%s ", vendorId, szApplicationName);
  427. return gFactory.AddContentApp(szVendorName, vendorId, szApplicationName, productId, szApplicationVersion, manager);
  428. #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
  429. return kInvalidEndpointId;
  430. }
  431. EndpointId AddContentApp(const char * szVendorName, uint16_t vendorId, const char * szApplicationName, uint16_t productId,
  432. const char * szApplicationVersion, EndpointId endpointId, jobject manager)
  433. {
  434. #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
  435. ChipLogProgress(DeviceLayer, "AppImpl: AddContentApp vendorId=%d applicationName=%s ", vendorId, szApplicationName);
  436. return gFactory.AddContentApp(szVendorName, vendorId, szApplicationName, productId, szApplicationVersion, manager, endpointId);
  437. #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
  438. return kInvalidEndpointId;
  439. }
  440. EndpointId RemoveContentApp(EndpointId epId)
  441. {
  442. #if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
  443. ChipLogProgress(DeviceLayer, "AppImpl: RemoveContentApp endpointId=%d ", epId);
  444. return gFactory.RemoveContentApp(epId);
  445. #endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
  446. return kInvalidEndpointId;
  447. }
  448. void ReportAttributeChange(EndpointId epId, chip::ClusterId clusterId, chip::AttributeId attributeId)
  449. {
  450. MatterReportingAttributeChangeCallback(epId, clusterId, attributeId);
  451. }
  452. void AddSelfVendorAsAdmin()
  453. {
  454. uint16_t value;
  455. if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetVendorId(value) != CHIP_NO_ERROR)
  456. {
  457. ChipLogDetail(Discovery, "AppImpl addSelfVendorAsAdmin Vendor ID not known");
  458. }
  459. else
  460. {
  461. gFactory.AddAdminVendorId(value);
  462. }
  463. }