Device Config OKIDL
Device Config OKIDL
Important: Amazon Confidential. This is pre-release technical documentation for an upcoming product that
has not been released to the public.
DeviceConfig is an Omnikit interface which provides APIs for querying and modifying device
configurations in addition to sending notifications on configuration updates. DeviceConfig acts as
a central data store for system-wide configurations and provides APIs for querying and modifying
configurations. These APIs are part of the IDL file
device_config_2024_01.idl and are implemented by
/com.amazon.kepler.experinental.device_config_2024_01
Access Control
DeviceConfig's APIs are access-controlled. Device configuration privileges are derived from device
configurations themselves; this section will explain DeviceConfig read and write privileges and
demonstrate usage in an application manifest.
Read Privileges
com.amazon.devconf.privilege.{group}.{key}
This privilege allows for retrieving a device configuration at key granularity. The privilege
com.amazon.devconf.privilege.{group}
com.amazon.devconf.privilege.{group}.{key}.write
DeviceConfig allows privileges to operate at key granularity (as shown above) as well as at group
granularity. In order to modify a device configuration within a specific group {group}, the
corresponding privilege can be:
com.amazon.devconf.privilege.{group}.write
Application Manifest
Manifest v1
schema-version = 1
[package]
id = "com.amazon.device-config.sample"
version = "1.0.0"
title = "DeviceConfig Sample Application Package"
[components]
[[components.interactive]]
id = "com.amazon.device-config.main"
library-name = "device_config_app"
categories = ["com.amazon.category.main"]
[needs]
[[needs.privilege]]
id = "com.amazon.devconf.privilege.configuration.locale"
For each privilege needed by the application, it will have an accompanying [[needs.privilege]]
subsection in its [needs] section.
DeviceConfig provides two APIs for retrieving device configuration values: get() to retrieve a
single device configuration value, and getArray() for retrieving a list of device configuration
values.
This section demonstrates querying device configuration values with both APIs:
using apmf::iface::com::amazon::kepler::experimental::device_config_2024_01::
DeviceConfigNotFoundException;
using apmf::iface::com::amazon::kepler::experimental::device_config_2024_01::IDeviceConfig;
return proc->getComponent(s_component).TryQueryInterface<IDeviceConfig>();
}
void getConfigValue() {
apmf::Ptr<IDeviceConfig> component = getIDeviceConfig();
if (component == nullptr) {
/* IDeviceConfig component not found */
return;
}
try {
apmf::String value = component->get(g_configLocale);
} catch (const apmf::IoError& e) {
/* Error communicating with DeviceConfigService server */
} catch (const apmf::InvalidArgumentError& e) {
/* Invalid device configuration input */
} catch (const apmf::SecurityError& e) {
/* No permissions */
} catch (const DeviceConfigNotFoundException& e) {
/* Non-fatal exception, device configuration queried has no value */
} catch (const apmf::BaseError& e) {
/* Catch all */
}
}
void getConfigValues() {
apmf::Ptr<IDeviceConfig> component = getIDeviceConfig();
if (component == nullptr) {
/* IDeviceConfig component not found */
return;
}
try {
apmf::Array<apmf::String> configs{g_configLocale, g_configTimeZone};
apmf::Array<apmf::String> values = component->getArray(configs);
} catch (const apmf::IoError& e) {
/* Error communicating with DeviceConfigService server */
} catch (const apmf::InvalidArgumentError& e) {
/* Invalid device configuration input */
} catch (const apmf::SecurityError& e) {
/* No permissions */
} catch (const apmf::BaseError& e) {
/* Catch all */
DeviceConfig provides a set() API which takes in a device configuration and a value. This API will
modify the device configuration to be the value and persist it across device reboots.
NOTE: Device configuration values are limited to 1,024 characters (1KB) to provide fast
data retrieval and modification.
NOTE: Device configuration values are not encrypted.
NOTE: If an empty string is provided as a device configuration value, the device configuration
will be removed from DeviceConfig. Subsequent get() calls to this device configuration will throw
a DeviceConfigNotFoundException until a non-empty value is set.
void setConfigValue() {
apmf::Ptr<IDeviceConfig> component = getIDeviceConfig();
if (component == nullptr) {
/* IDeviceConfig component not found */
return;
}
try {
apmf::String value{"America/Los_Angeles"};
component->set(g_configTimeZone, value);
} catch (const apmf::IoError& e) {
/* Error communicating with DeviceConfigService server */
} catch (const apmf::OutOfBoundsError& e) {
/* Value set exceeds maximum device configuration value size */
} catch (const apmf::InvalidArgumentError& e) {
/* Invalid device configuration input */
} catch (const apmf::SecurityError& e) {
/* No permissions */
} catch (const apmf::NotSupportedError& e) {
/* Attempting to set a read-only device configuration */
} catch (const apmf::BaseError& e) {
/* Catch all */
}
}
Update Notification
DeviceConfig uses Kepler Messaging to send notifications on device configuration value updates.
Whenever a device configuration value has been updated, DeviceConfig will send a message using the
URI:
broadcast://*/com.amazon.devconf/system/{group}/{key}
The Message sent will include an attachment DeviceConfigChangeAttachment which will contain the
new value the device configuration has been set to. This may be retrieved by the attachment's
updatedValue() API.
This section demonstrates usage of the Kepler Messaging APIs to setup a notification callback
whenever a device configuration has been changed.
using apmf::iface::com::amazon::kepler::experimental::device_config_2024_01::DeviceConfigChangeAttachment;
using apmf::iface::com::amazon::kepler::experimental::device_config_2024_01::IDeviceConfig;
using apmf::iface::com::amazon::kepler::experimental_mr33::messaging::IKeplerMessagingModule;
using apmf::iface::com::amazon::kepler::experimental_mr33::messaging::IMessage;
using apmf::iface::com::amazon::kepler::experimental_mr33::messaging::IMessageChannel;
using apmf::iface::com::amazon::kepler::experimental_mr33::messaging::IMessageFilter;
using apmf::iface::com::amazon::kepler::experimental_mr33::messaging::IMessageListener;
std::cout << "New device configuration value: " << attachment->updatedValue() << std::endl;
}
void listen() {
apmf::Ptr<apmf::IProcess> proc = apmf::GetProcessObject();
auto component = proc->getComponent("/com.amazon.kepler.experimental_mr33.messaging")
.TryQueryInterface<IKeplerMessagingModule>();
if (component == nullptr) {
/* IKeplerMessagingModule not found */
return;
}
apmf::Array<Ptr<IMessageFilter>> filterArray{};
filterArray.push_back(component->makeMessageFilterBuilder()->baseUri(g_topic)->build());
g_channel->registerMessageFilter(filterArray);
}