Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Draft] Re-Implement App Install flow #33982

Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -5324,6 +5324,10 @@ cluster ApplicationBasic = 1293 {
kActiveVisibleFocus = 1;
kActiveHidden = 2;
kActiveVisibleNotFocus = 3;
kNotInstalled = 4;
kInstalling = 5;
kInstallationFailed = 6;
kInstalled = 7;
}

struct ApplicationStruct {
8 changes: 8 additions & 0 deletions examples/placeholder/linux/apps/app1/config.matter
Original file line number Diff line number Diff line change
@@ -8014,6 +8014,10 @@ cluster ApplicationBasic = 1293 {
kActiveVisibleFocus = 1;
kActiveHidden = 2;
kActiveVisibleNotFocus = 3;
kNotInstalled = 4;
kInstalling = 5;
kInstallationFailed = 6;
kInstalled = 7;
}

struct ApplicationStruct {
@@ -8046,6 +8050,10 @@ cluster ApplicationBasic = 1293 {
kActiveVisibleFocus = 1;
kActiveHidden = 2;
kActiveVisibleNotFocus = 3;
kNotInstalled = 4;
kInstalling = 5;
kInstallationFailed = 6;
kInstalled = 7;
}

struct ApplicationStruct {
8 changes: 8 additions & 0 deletions examples/placeholder/linux/apps/app2/config.matter
Original file line number Diff line number Diff line change
@@ -7971,6 +7971,10 @@ cluster ApplicationBasic = 1293 {
kActiveVisibleFocus = 1;
kActiveHidden = 2;
kActiveVisibleNotFocus = 3;
kNotInstalled = 4;
kInstalling = 5;
kInstallationFailed = 6;
kInstalled = 7;
}

struct ApplicationStruct {
@@ -8003,6 +8007,10 @@ cluster ApplicationBasic = 1293 {
kActiveVisibleFocus = 1;
kActiveHidden = 2;
kActiveVisibleNotFocus = 3;
kNotInstalled = 4;
kInstalling = 5;
kInstallationFailed = 6;
kInstalled = 7;
}

struct ApplicationStruct {
2 changes: 1 addition & 1 deletion examples/tv-app/android/java/AppPlatform-JNI.cpp
Original file line number Diff line number Diff line change
@@ -128,7 +128,7 @@ std::vector<ContentApp::SupportedCluster> convert_to_cpp(JNIEnv * env, jobject s
// Find Java classes. WARNING: Reflection
jclass collectionClass = env->FindClass("java/util/Collection");
jclass iteratorClass = env->FindClass("java/util/Iterator");
jclass clusterClass = env->FindClass("com/matter/tv/server/tvapp/SupportedCluster");
jclass clusterClass = env->FindClass("com/matter/tv/server/tvapp/ContentAppSupportedCluster");
if (collectionClass == nullptr || iteratorClass == nullptr || clusterClass == nullptr)
{
return {};
16 changes: 16 additions & 0 deletions examples/tv-app/android/java/TVApp-JNI.cpp
Original file line number Diff line number Diff line change
@@ -240,6 +240,21 @@ class MyPincodeService : public PasscodeService
};
MyPincodeService gMyPincodeService;

class MyAppInstallationService : public AppInstallationService
{
bool LookupTargetContentApp(uint16_t vendorId, uint16_t productId) override
{
return ContentAppPlatform::GetInstance().LoadContentAppByClient(vendorId, productId) != nullptr;
}

void AddUninstalledContentApp(uint16_t vendorId, uint16_t productId) override
{
// TODO: Add Uninstall Content App For Android
}
};

MyAppInstallationService gMyAppInstallationService;

class MyPostCommissioningListener : public PostCommissioningListener
{
void CommissioningCompleted(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr,
@@ -372,6 +387,7 @@ void TvAppJNI::InitializeCommissioner(JNIMyUserPrompter * userPrompter)
if (cdc != nullptr && userPrompter != nullptr)
{
cdc->SetPasscodeService(&gMyPincodeService);
cdc->SetAppInstallationService(&gMyAppInstallationService);
cdc->SetUserPrompter(userPrompter);
cdc->SetPostCommissioningListener(&gMyPostCommissioningListener);
}
4 changes: 4 additions & 0 deletions examples/tv-app/tv-common/include/AppTv.h
Original file line number Diff line number Diff line change
@@ -149,6 +149,10 @@ class DLL_EXPORT ContentAppFactoryImpl : public ContentAppFactory
void InstallContentApp(uint16_t vendorId, uint16_t productId);
// Remove the app from the list of mContentApps
bool UninstallContentApp(uint16_t vendorId, uint16_t productId);
// Add uninstalled content app to the list of mContentApps
void AddUninstalledContentApp(uint16_t vendorId, uint16_t productId);
// Print mContentApps and endpoints
void PrintInstalledApps();

protected:
std::vector<std::unique_ptr<ContentAppImpl>> mContentApps;
22 changes: 22 additions & 0 deletions examples/tv-app/tv-common/shell/AppTvShellCommands.cpp
Original file line number Diff line number Diff line change
@@ -205,6 +205,15 @@ static CHIP_ERROR PrintAllCommands()
streamer_printf(sout,
" add-admin-vendor <vid> Add vendor ID to list which will receive admin privileges. Usage: app "
"add-admin-vendor 65521\r\n");
streamer_printf(sout,
" app list List installed apps. Usage: app list");
streamer_printf(sout,
" app install <vid> <pid> Install app with given vendor ID and product ID. Usage: app install "
"65521 32768\r\n");
streamer_printf(
sout,
" app uninstall <vid> <pid> Uinstall app at given vendor ID and product ID. Usage: app uninstall "
"65521 32768\r\n");
#endif // CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
#if CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE
streamer_printf(sout, " print-app-access Print all ACLs for app platform fabric. Usage: app print-app-access\r\n");
@@ -243,6 +252,19 @@ static CHIP_ERROR AppPlatformHandler(int argc, char ** argv)

return CHIP_NO_ERROR;
}

else if (strcmp(argv[0], "list") == 0)
{
if (argc > 1)
{
return PrintAllCommands();
}

ContentAppFactoryImpl * factory = GetContentAppFactoryImpl();
factory->PrintInstalledApps();

return CHIP_NO_ERROR;
}
else if (strcmp(argv[0], "install") == 0)
{
if (argc < 2)
129 changes: 107 additions & 22 deletions examples/tv-app/tv-common/src/AppTv.cpp
Original file line number Diff line number Diff line change
@@ -98,12 +98,6 @@ class MyUserPrompter : public UserPrompter

// tv should override this with a dialog prompt
inline void PromptCommissioningFailed(const char * commissioneeName, CHIP_ERROR error) override { return; }

// tv should override this with a dialog prompt
inline void PromptForAppInstallOKPermission(uint16_t vendorId, uint16_t productId, const char * commissioneeName) override
{
return;
}
};

MyUserPrompter gMyUserPrompter;
@@ -158,6 +152,11 @@ class MyAppInstallationService : public AppInstallationService
{
return ContentAppPlatform::GetInstance().LoadContentAppByClient(vendorId, productId) != nullptr;
}

void AddUninstalledContentApp(uint16_t vendorId, uint16_t productId) override
{
GetContentAppFactoryImpl()->AddUninstalledContentApp(vendorId, productId);
}
};

MyAppInstallationService gMyAppInstallationService;
@@ -571,6 +570,21 @@ void ContentAppFactoryImpl::AddAdminVendorId(uint16_t vendorId)
mAdminVendorIds.push_back(vendorId);
}

void ContentAppFactoryImpl::AddUninstalledContentApp(uint16_t vendorId, uint16_t productId)
{
auto make_default_supported_clusters = []() {
return std::vector<ContentApp::SupportedCluster>{ { Descriptor::Id }, { ApplicationBasic::Id },
{ KeypadInput::Id }, { ApplicationLauncher::Id } };
};

auto ptr = std::make_unique<ContentAppImpl>("Vendor1", vendorId, "exampleid", productId, "Version1",
"0", make_default_supported_clusters());

ptr.get()->GetApplicationBasicDelegate()->SetApplicationStatus(app::Clusters::ApplicationBasic::ApplicationStatusEnum::kNotInstalled);

mContentApps.emplace_back(std::move(ptr));
}

void ContentAppFactoryImpl::InstallContentApp(uint16_t vendorId, uint16_t productId)
{
auto make_default_supported_clusters = []() {
@@ -583,28 +597,48 @@ void ContentAppFactoryImpl::InstallContentApp(uint16_t vendorId, uint16_t produc
ChipLogProgress(DeviceLayer, "ContentAppFactoryImpl: InstallContentApp vendorId=%d productId=%d ", vendorId, productId);
if (vendorId == 1 && productId == 11)
{
mContentApps.emplace_back(std::make_unique<ContentAppImpl>("Vendor1", vendorId, "exampleid", productId, "Version1",
"34567890", make_default_supported_clusters()));
auto ptr = std::make_unique<ContentAppImpl>("Vendor1", vendorId, "exampleid", productId, "Version1",
"34567890", make_default_supported_clusters());

ptr.get()->GetApplicationBasicDelegate()->SetApplicationStatus(app::Clusters::ApplicationBasic::ApplicationStatusEnum::kInstalled);

mContentApps.emplace_back(std::move(ptr));
}
else if (vendorId == 65521 && productId == 32768)
else if (vendorId == 65521 && productId == 32769)
{
mContentApps.emplace_back(std::make_unique<ContentAppImpl>("Vendor2", vendorId, "exampleString", productId, "Version2",
"20202021", make_default_supported_clusters()));
auto ptr = std::make_unique<ContentAppImpl>("Vendor2", vendorId, "exampleString", productId, "Version2",
"20202021", make_default_supported_clusters());

ptr.get()->GetApplicationBasicDelegate()->SetApplicationStatus(app::Clusters::ApplicationBasic::ApplicationStatusEnum::kInstalled);

mContentApps.emplace_back(std::move(ptr));
}
else if (vendorId == 9050 && productId == 22)
{
mContentApps.emplace_back(std::make_unique<ContentAppImpl>("Vendor3", vendorId, "App3", productId, "Version3", "20202021",
make_default_supported_clusters()));
{
auto ptr = std::make_unique<ContentAppImpl>("Vendor3", vendorId, "App3", productId, "Version3", "20202021",
make_default_supported_clusters());

ptr.get()->GetApplicationBasicDelegate()->SetApplicationStatus(app::Clusters::ApplicationBasic::ApplicationStatusEnum::kInstalled);

mContentApps.emplace_back(std::move(ptr));
}
else if (vendorId == 1111 && productId == 22)
{
mContentApps.emplace_back(std::make_unique<ContentAppImpl>("TestSuiteVendor", vendorId, "applicationId", productId, "v2",
"20202021", make_default_supported_clusters()));
auto ptr = std::make_unique<ContentAppImpl>("TestSuiteVendor", vendorId, "applicationId", productId, "v2",
"20202021", make_default_supported_clusters());

ptr.get()->GetApplicationBasicDelegate()->SetApplicationStatus(app::Clusters::ApplicationBasic::ApplicationStatusEnum::kInstalled);

mContentApps.emplace_back(std::move(ptr));
}
else
{
mContentApps.emplace_back(std::make_unique<ContentAppImpl>("NewAppVendor", vendorId, "newAppApplicationId", productId, "v2",
"20202021", make_default_supported_clusters()));
auto ptr = std::make_unique<ContentAppImpl>("NewAppVendor", vendorId, "newAppApplicationId", productId, "v2",
"20202021", make_default_supported_clusters());

ptr.get()->GetApplicationBasicDelegate()->SetApplicationStatus(app::Clusters::ApplicationBasic::ApplicationStatusEnum::kInstalled);

mContentApps.emplace_back(std::move(ptr));
}
}

@@ -627,6 +661,7 @@ bool ContentAppFactoryImpl::UninstallContentApp(uint16_t vendorId, uint16_t prod
app->GetApplicationBasicDelegate()->HandleGetVendorId(),
app->GetApplicationBasicDelegate()->HandleGetProductId());
mContentApps.erase(mContentApps.begin() + index);
// TODO: call ContentAppPlatform->RemoveContentApp(ids...)
return true;
}

@@ -635,6 +670,46 @@ bool ContentAppFactoryImpl::UninstallContentApp(uint16_t vendorId, uint16_t prod
return false;
}

// Helper function to convert enum to string
std::string ApplicationBasicStatusToString(app::Clusters::ApplicationBasic::ApplicationStatusEnum status)
{
switch (status)
{
case app::Clusters::ApplicationBasic::ApplicationStatusEnum::kStopped:
return "kStopped";
case app::Clusters::ApplicationBasic::ApplicationStatusEnum::kActiveVisibleFocus:
return "kActiveVisibleFocus";
case app::Clusters::ApplicationBasic::ApplicationStatusEnum::kActiveHidden:
return "kActiveHidden";
case app::Clusters::ApplicationBasic::ApplicationStatusEnum::kActiveVisibleNotFocus:
return "kActiveVisibleNotFocus";
case app::Clusters::ApplicationBasic::ApplicationStatusEnum::kNotInstalled:
return "kNotInstalled";
case app::Clusters::ApplicationBasic::ApplicationStatusEnum::kInstalling:
return "kInstalling";
case app::Clusters::ApplicationBasic::ApplicationStatusEnum::kInstallationFailed:
return "kInstallationFailed";
case app::Clusters::ApplicationBasic::ApplicationStatusEnum::kInstalled:
return "kInstalled";
case app::Clusters::ApplicationBasic::ApplicationStatusEnum::kUnknownEnumValue:
return "kUnknownEnumValue";
default:
return "UnknownEnumValue";
}
}

void ContentAppFactoryImpl::PrintInstalledApps()
{
for (auto & contentApp : mContentApps)
{
auto app = contentApp.get();

ChipLogProgress(DeviceLayer, "Content app vid=%d pid=%d is on ep=%d with app's basic status=%s", app->GetApplicationBasicDelegate()->HandleGetVendorId(),
app->GetApplicationBasicDelegate()->HandleGetProductId(), app->GetEndpointId(),
ApplicationBasicStatusToString(app->GetApplicationBasicDelegate()->HandleGetStatus()).c_str());
}
}

Access::Privilege ContentAppFactoryImpl::GetVendorPrivilege(uint16_t vendorId)
{
for (size_t i = 0; i < mAdminVendorIds.size(); ++i)
@@ -689,12 +764,22 @@ std::list<ClusterId> ContentAppFactoryImpl::GetAllowedClusterListForStaticEndpoi
CHIP_ERROR AppTvInit()
{
#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
// test data for apps
constexpr uint16_t kApp1VendorId = 1;
constexpr uint16_t kApp1ProductId = 11;
constexpr uint16_t kApp2VendorId = 65521;
constexpr uint16_t kApp2ProductId = 32769;
constexpr uint16_t kApp3VendorId = 9050;
constexpr uint16_t kApp3ProductId = 22;
constexpr uint16_t kApp4VendorId = 1111;
constexpr uint16_t kApp4ProductId = 22;

ContentAppPlatform::GetInstance().SetupAppPlatform();
ContentAppPlatform::GetInstance().SetContentAppFactory(&gFactory);
gFactory.InstallContentApp((uint16_t) 1, (uint16_t) 11);
gFactory.InstallContentApp((uint16_t) 65521, (uint16_t) 32768);
gFactory.InstallContentApp((uint16_t) 9050, (uint16_t) 22);
gFactory.InstallContentApp((uint16_t) 1111, (uint16_t) 22);
gFactory.InstallContentApp(kApp1VendorId, kApp1ProductId);
gFactory.InstallContentApp(kApp2VendorId, kApp2ProductId);
gFactory.InstallContentApp(kApp3VendorId, kApp3ProductId);
gFactory.InstallContentApp(kApp4VendorId, kApp4ProductId);
uint16_t value;
if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetVendorId(value) != CHIP_NO_ERROR)
{
4 changes: 4 additions & 0 deletions examples/tv-app/tv-common/tv-app.matter
Original file line number Diff line number Diff line change
@@ -2988,6 +2988,10 @@ cluster ApplicationBasic = 1293 {
kActiveVisibleFocus = 1;
kActiveHidden = 2;
kActiveVisibleNotFocus = 3;
kNotInstalled = 4;
kInstalling = 5;
kInstallationFailed = 6;
kInstalled = 7;
}

struct ApplicationStruct {
Original file line number Diff line number Diff line change
@@ -2450,6 +2450,10 @@ cluster ApplicationBasic = 1293 {
kActiveVisibleFocus = 1;
kActiveHidden = 2;
kActiveVisibleNotFocus = 3;
kNotInstalled = 4;
kInstalling = 5;
kInstallationFailed = 6;
kInstalled = 7;
}

struct ApplicationStruct {
Original file line number Diff line number Diff line change
@@ -91,7 +91,7 @@ class Delegate

protected:
CatalogVendorApp mCatalogVendorApp;
ApplicationStatusEnum mApplicationStatus = ApplicationStatusEnum::kStopped;
ApplicationStatusEnum mApplicationStatus = ApplicationStatusEnum::kNotInstalled;
};

} // namespace ApplicationBasic
Original file line number Diff line number Diff line change
@@ -225,6 +225,7 @@ CHIP_ERROR ApplicationBasicAttrAccess::ReadApplicationAttribute(app::AttributeVa

CHIP_ERROR ApplicationBasicAttrAccess::ReadStatusAttribute(app::AttributeValueEncoder & aEncoder, Delegate * delegate)
{
ChipLogProgress(DeviceLayer, "Here 1");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not a useful log.

ApplicationStatusEnum status = delegate->HandleGetStatus();
return aEncoder.Encode(status);
}
Original file line number Diff line number Diff line change
@@ -51,5 +51,9 @@ limitations under the License.
<item name="ActiveVisibleFocus" value="0x01"/>
<item name="ActiveHidden" value="0x02"/>
<item name="ActiveVisibleNotFocus" value="0x03"/>
<item name="NotInstalled" value="0x04"/>
<item name="Installing" value="0x05"/>
<item name="InstallationFailed" value="0x06"/>
<item name="Installed" value="0x07"/>
Comment on lines +54 to +57
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see these in the spec. Why are we adding random non-spec bits here?

</enum>
</configurator>
Loading