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

Add basic support for reporting application installation status #33614

Closed
wants to merge 36 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
2ddf563
Add basic logic for reporting application installation status
lazarkov May 27, 2024
970a793
Update documentation and clean up the code
lazarkov May 27, 2024
963ab2f
Merge branch 'master' into feature/app-installation-status-report
lazarkov May 27, 2024
a42b4a0
Restyled by whitespace
restyled-commits May 27, 2024
4af41f7
Restyled by clang-format
restyled-commits May 27, 2024
71c1bbf
Merge branch 'master' into feature/app-installation-status-report
lazarkov May 28, 2024
5a47bcc
Update app installation code
lazarkov May 28, 2024
fd4769e
Update with comment
lazarkov May 28, 2024
007460c
Restyled by whitespace
restyled-commits May 28, 2024
22d9239
Restyled by clang-format
restyled-commits May 28, 2024
83753fe
Merge branch 'master' into feature/app-installation-status-report
lazarkov May 28, 2024
90e114f
Merge branch 'master' into feature/app-installation-status-report
lazarkov May 28, 2024
ca17606
Merge branch 'master' into feature/app-installation-status-report
lazarkov May 28, 2024
e37775f
Merge branch 'master' into feature/app-installation-status-report
lazarkov May 28, 2024
05c6db8
Merge branch 'master' into feature/app-installation-status-report
lazarkov May 29, 2024
8e42f42
Update code per comments
lazarkov May 29, 2024
4ae3a36
Restyled by whitespace
restyled-commits May 29, 2024
106d30c
Restyled by clang-format
restyled-commits May 29, 2024
d396f5d
Merge branch 'master' into feature/app-installation-status-report
lazarkov May 29, 2024
30769d4
Merge branch 'master' into feature/app-installation-status-report
lazarkov May 29, 2024
40eb3df
Update examples/tv-app/tv-common/shell/AppTvShellCommands.cpp
lazarkov May 30, 2024
8751e24
Merge branch 'master' into feature/app-installation-status-report
lazarkov May 30, 2024
8246f0e
Restyled by clang-format
restyled-commits May 30, 2024
d373a0f
Merge branch 'master' into feature/app-installation-status-report
lazarkov May 31, 2024
9def1a3
Merge branch 'master' into feature/app-installation-status-report
lazarkov Jun 3, 2024
0184744
Update code per comments
lazarkov Jun 4, 2024
de7b390
Restyled by whitespace
restyled-commits Jun 4, 2024
2ca4374
Restyled by clang-format
restyled-commits Jun 4, 2024
f401ba7
Merge branch 'master' into feature/app-installation-status-report
lazarkov Jun 4, 2024
f7f8d3d
Merge branch 'master' into feature/app-installation-status-report
lazarkov Jun 4, 2024
6c2fa94
Merge branch 'master' into feature/app-installation-status-report
lazarkov Jun 4, 2024
bc2ec4a
Merge branch 'master' into feature/app-installation-status-report
lazarkov Jun 4, 2024
ae6715d
Merge branch 'master' into feature/app-installation-status-report
lazarkov Jun 5, 2024
c9e783f
Merge branch 'master' into feature/app-installation-status-report
lazarkov Jun 5, 2024
1f7ba4e
Merge branch 'master' into feature/app-installation-status-report
lazarkov Jun 6, 2024
7d35e6c
Merge branch 'master' into feature/app-installation-status-report
lazarkov Jun 12, 2024
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
18 changes: 18 additions & 0 deletions examples/tv-app/android/java/TVApp-JNI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,23 @@ 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;
}

// TODO: Dummy code for Android OS, needs to be updated with package manager
// retrieving correct app's installation status
CommissionerDeclaration::CdError GetAppInstallationErrorCode(uint16_t vendorId, uint16_t productId) override
{
return CommissionerDeclaration::CdError::kAppInstallConsentPending;
}
};

MyAppInstallationService gMyAppInstallationService;

class MyPostCommissioningListener : public PostCommissioningListener
{
void CommissioningCompleted(uint16_t vendorId, uint16_t productId, NodeId nodeId, Messaging::ExchangeManager & exchangeMgr,
Expand Down Expand Up @@ -373,6 +390,7 @@ void TvAppJNI::InitializeCommissioner(JNIMyUserPrompter * userPrompter)
{
cdc->SetPasscodeService(&gMyPincodeService);
cdc->SetUserPrompter(userPrompter);
cdc->SetAppInstallationService(&gMyAppInstallationService);
cdc->SetPostCommissioningListener(&gMyPostCommissioningListener);
}

Expand Down
7 changes: 7 additions & 0 deletions examples/tv-app/tv-common/include/AppTv.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,10 +147,17 @@ 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);
// Set App's Installation Error Status
void SetAppInstallationErrorStatus(uint16_t vendorId, uint16_t productId,
Protocols::UserDirectedCommissioning::CommissionerDeclaration::CdError errorStatus);
// Get App's Installation Status
Protocols::UserDirectedCommissioning::CommissionerDeclaration::CdError GetAppInstallationStatus(uint16_t vendorId,
uint16_t productId);

protected:
std::vector<std::unique_ptr<ContentAppImpl>> mContentApps;
std::vector<uint16_t> mAdminVendorIds{};
std::map<std::string, Protocols::UserDirectedCommissioning::CommissionerDeclaration::CdError> mAppInstallationStatus{};
};

} // namespace AppPlatform
Expand Down
33 changes: 33 additions & 0 deletions examples/tv-app/tv-common/shell/AppTvShellCommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,18 @@ 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 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");
streamer_printf(sout,
" app setinstallerrorstatus <vid> <pid> Set app's installation error status for a given vendor "
"ID and product ID. "
"Usage: app setinstallerrorstatus 65521 32768 13. Installation error status can be found at: "
"UserDirectedCommissioning.h\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");
Expand Down Expand Up @@ -292,6 +304,27 @@ static CHIP_ERROR AppPlatformHandler(int argc, char ** argv)

return CHIP_NO_ERROR;
}
else if (strcmp(argv[0], "setinstallerrorstatus") == 0)
{
if (argc < 3)
{
return PrintAllCommands();
}
char * eptr;

uint16_t vid = (uint16_t) strtol(argv[1], &eptr, 10);
uint16_t pid = (uint16_t) strtol(argv[2], &eptr, 10);
uint16_t appInstallationErrorStatus = (uint16_t) strtol(argv[3], &eptr, 10);

ContentAppFactoryImpl * factory = GetContentAppFactoryImpl();
factory->SetAppInstallationErrorStatus(
vid, pid,
static_cast<Protocols::UserDirectedCommissioning::CommissionerDeclaration::CdError>(appInstallationErrorStatus));

ChipLogProgress(DeviceLayer, "set app installation status");

return CHIP_NO_ERROR;
}
else if (strcmp(argv[0], "add") == 0)
{
if (argc < 2)
Expand Down
59 changes: 55 additions & 4 deletions examples/tv-app/tv-common/src/AppTv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ class MyAppInstallationService : public AppInstallationService
{
return ContentAppPlatform::GetInstance().LoadContentAppByClient(vendorId, productId) != nullptr;
}

CommissionerDeclaration::CdError GetAppInstallationErrorCode(uint16_t vendorId, uint16_t productId) override
{
ContentAppFactoryImpl * factory = GetContentAppFactoryImpl();
return factory->GetAppInstallationStatus(vendorId, productId);
}
};

MyAppInstallationService gMyAppInstallationService;
Expand Down Expand Up @@ -627,6 +633,41 @@ bool ContentAppFactoryImpl::UninstallContentApp(uint16_t vendorId, uint16_t prod
return false;
}

std::string createSearchIndex(uint16_t vendorId, uint16_t productId)
{
// Format the IDs into a string
std::string formattedString = std::to_string(vendorId) + ":" + std::to_string(productId);
return formattedString;
}

void ContentAppFactoryImpl::SetAppInstallationErrorStatus(uint16_t vendorId, uint16_t productId,
CommissionerDeclaration::CdError errorStatus)
{
std::string searchIndex = createSearchIndex(vendorId, productId);
std::map<std::string, Protocols::UserDirectedCommissioning::CommissionerDeclaration::CdError>::iterator it;
it = mAppInstallationStatus.find(searchIndex);
if (it != mAppInstallationStatus.end())
{
mAppInstallationStatus[searchIndex] = errorStatus;
return;
}

mAppInstallationStatus.insert({ searchIndex, errorStatus });
}

CommissionerDeclaration::CdError ContentAppFactoryImpl::GetAppInstallationStatus(uint16_t vendorId, uint16_t productId)
{
std::string searchIndex = createSearchIndex(vendorId, productId);
std::map<std::string, Protocols::UserDirectedCommissioning::CommissionerDeclaration::CdError>::iterator it;
it = mAppInstallationStatus.find(searchIndex);
if (it != mAppInstallationStatus.end())
{
return mAppInstallationStatus[searchIndex];
}

return CommissionerDeclaration::CdError::kAppInstallConsentPending;
}

Access::Privilege ContentAppFactoryImpl::GetVendorPrivilege(uint16_t vendorId)
{
for (size_t i = 0; i < mAdminVendorIds.size(); ++i)
Expand Down Expand Up @@ -681,12 +722,22 @@ std::list<ClusterId> ContentAppFactoryImpl::GetAllowedClusterListForStaticEndpoi
CHIP_ERROR AppTvInit()
{
#if CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED
// test data for apps
const uint16_t APP1_VENDOR_ID = 1;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: naming should probably be kCamelCasename and using constexpr.

Suggested change
const uint16_t APP1_VENDOR_ID = 1;
constexpr uint16_t kApp1VendorId = 1;

const uint16_t APP1_PRODUCT_ID = 11;
const uint16_t APP2_VENDOR_ID = 65521;
const uint16_t APP2_PRODUCT_ID = 32769;
const uint16_t APP3_VENDOR_ID = 9050;
const uint16_t APP3_PRODUCT_ID = 22;
const uint16_t APP4_VENDOR_ID = 1111;
const uint16_t APP4_PRODUCT_ID = 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(APP1_VENDOR_ID, APP1_PRODUCT_ID);
gFactory.InstallContentApp(APP2_VENDOR_ID, APP2_PRODUCT_ID);
gFactory.InstallContentApp(APP3_VENDOR_ID, APP3_PRODUCT_ID);
gFactory.InstallContentApp(APP4_VENDOR_ID, APP4_PRODUCT_ID);
uint16_t value;
if (DeviceLayer::GetDeviceInstanceInfoProvider()->GetVendorId(value) != CHIP_NO_ERROR)
{
Expand Down
13 changes: 8 additions & 5 deletions src/controller/CommissionerDiscoveryController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -230,11 +230,6 @@ void CommissionerDiscoveryController::InternalOk()
{
ChipLogDetail(AppServer, "UX InternalOk: app not installed.");

// notify client that app will be installed
CommissionerDeclaration cd;
cd.SetErrorCode(CommissionerDeclaration::CdError::kAppInstallConsentPending);
mUdcServer->SendCDCMessage(cd, Transport::PeerAddress::UDP(client->GetPeerAddress().GetIPAddress(), client->GetCdPort()));

// dialog
ChipLogDetail(Controller, "------PROMPT USER: %s is requesting to install app on this TV. vendorId=%d, productId=%d",
client->GetDeviceName(), client->GetVendorId(), client->GetProductId());
Expand All @@ -244,6 +239,14 @@ void CommissionerDiscoveryController::InternalOk()
mUserPrompter->PromptForAppInstallOKPermission(client->GetVendorId(), client->GetProductId(), client->GetDeviceName());
}
ChipLogDetail(Controller, "------Via Shell Enter: app install <pid> <vid>");

CommissionerDeclaration::CdError appInstallStatus =
mAppInstallationService->GetAppInstallationErrorCode(client->GetVendorId(), client->GetProductId());

// notify client the current app's installation status
CommissionerDeclaration cd;
cd.SetErrorCode(appInstallStatus);
mUdcServer->SendCDCMessage(cd, Transport::PeerAddress::UDP(client->GetPeerAddress().GetIPAddress(), client->GetCdPort()));
return;
}

Expand Down
15 changes: 15 additions & 0 deletions src/controller/CommissionerDiscoveryController.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,21 @@ class DLL_EXPORT AppInstallationService
*/
virtual bool LookupTargetContentApp(uint16_t vendorId, uint16_t productId) = 0;

/**
* @brief
* Called to get app's installation error code.
*
* CdError status is designed for CommissionerDeclaration and should be set by using SetErrorCode() and
* sent back to the client as a CDC Message. It is expected that app during installation can return following errors:
* kNoError, kAppInstallConsentPending, kAppInstalling, kAppInstallFailed, kAppInstalledRetryNeeded
Copy link
Contributor

Choose a reason for hiding this comment

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

If this is a subset of errors, the comment should explain why only this subset will be returned here (and that it is a subset).

If this is an exhaustive set, then we should NOT have this list as this would mean we have to maintain the list in sync.

Overall listing anything except kNoError or special one-offs adds a maintenance burden to update the comment if the underlying code changes (and worse, you return a generic CdError yet your api claims to never return the entire set of errors and if clients rely on that, they may break on updates).

How about something like:

Returns a subset of CDError that are specific during application instalation lifecycle. In particular:
  - kNoError means no error
  - kAppInstallConsentPending is returned if no application is available
  - other kApp* constants for lifecycle managemnt (kAppInstalling, kAppInstallFailed, kAppInstallRetryNeeded)
  - other CdError constants are EXPLICITLY DISALLOWED

unsure if the above comment is true ... however please see how it can be phrased to make expectations clear. Is for example kUnexpectedCommissionerPasscodeReady (random pick) possible here? it is a valid CdError value. How about kConfigurationFailed?

Should we maybe consider having a separate enum that is more restricted and that can be directly converted to a CdError instead?

*
* @param[in] vendorId The vendorId in the DNS-SD advertisement of the requesting commissionee.
* @param[in] productId The productId in the DNS-SD advertisement of the requesting commissionee.
*
*/
virtual chip::Protocols::UserDirectedCommissioning::CommissionerDeclaration::CdError
GetAppInstallationErrorCode(uint16_t vendorId, uint16_t productId) = 0;

virtual ~AppInstallationService() = default;
};

Expand Down
Loading