Skip to content

Commit

Permalink
April 2022 Release of the APL 1.9 compliant APL Client Library
Browse files Browse the repository at this point in the history
For more details on this release refer to CHANGELOG.md

To learn about APL see: https://developer.amazon.com/docs/alexa-presentation-language/understand-apl.html
  • Loading branch information
Robin Chen committed Apr 8, 2022
1 parent ac96cbc commit 53ed721
Show file tree
Hide file tree
Showing 86 changed files with 750 additions and 638 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

#ifndef APLCLIENT_EXTENSIONS_ATTENTIONSYSTEM_H
#define APLCLIENT_EXTENSIONS_ATTENTIONSYSTEM_H

#include "APLClient/Extensions/AplCoreExtensionInterface.h"

namespace APLClient {
namespace Extensions {
namespace AttentionSystem {

enum class AttentionState {
IDLE,
LISTENING,
THINKING,
SPEAKING
};

static const std::string URI = "aplext:attentionsystem:10";

/**
* The Attention system extension allows APL developers the ability to react to changes in the attention system state.
*/
class AplAttentionSystemExtension :
public AplCoreExtensionInterface,
public std::enable_shared_from_this<AplAttentionSystemExtension> {

public:
AplAttentionSystemExtension();

/// @name AplCoreExtensionInterface Functions
/// @{
std::string getUri() override;

apl::Object getEnvironment() override;

std::list<apl::ExtensionCommandDefinition> getCommandDefinitions() override;

std::list<apl::ExtensionEventHandler> getEventHandlers() override;

std::unordered_map<std::string, apl::LiveObjectPtr> getLiveDataObjects() override;

void applySettings(const apl::Object &settings) override;
/// @}

/// @name AplCoreExtensionEventCallbackInterface Functions
/// @{
void onExtensionEvent(
const std::string& uri,
const std::string& name,
const apl::Object& source,
const apl::Object& params,
unsigned int event,
std::shared_ptr<AplCoreExtensionEventCallbackResultInterface> resultCallback = nullptr
) override;
/// @}

/**
* Call to invoke the OnAttentionStateChanged ExtensionEventHandler and update the AttentionSystemState apl::LiveMap.
* It is expected that this is called on every change in the AttentionSystem's attention state.
*
* @param state The system's attention state
*/
void updateAttentionSystemState(const AttentionState& state);
private:
/// The document settings defined 'name' for the attentionSystemState data object
std::string m_attentionSystemStateName;

/// The @c apl::LiveMap for AttentionSystem attentionSystemState data.
apl::LiveMapPtr m_attentionSystemState;
};

using AplAttentionSystemExtensionionPtr = std::shared_ptr<AplAttentionSystemExtension>;

} // namespace AttentionSystem
} // namespace Extensions
} // namespace APLClient

#endif //APLCLIENT_EXTENSIONS_ATTENTIONSYSTEM_H

This file was deleted.

28 changes: 25 additions & 3 deletions APLClient/src/AplCoreConnectionManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include <apl/datasource/dynamicindexlistdatasourceprovider.h>
#include <apl/datasource/dynamictokenlistdatasourceprovider.h>
#include <apl/content/rootproperties.h>

namespace APLClient {

Expand Down Expand Up @@ -65,6 +66,8 @@ static const char AGENTNAME_KEY[] = "agentName";
static const char AGENTVERSION_KEY[] = "agentVersion";
static const char ALLOWOPENURL_KEY[] = "allowOpenUrl";
static const char DISALLOWVIDEO_KEY[] = "disallowVideo";
static const char DISALLOWDIALOG_KEY[] = "disallowDialog";
static const char DISALLOWEDITTEXT_KEY[] = "disallowEditText";
static const char ANIMATIONQUALITY_KEY[] = "animationQuality";
static const char SUPPORTED_EXTENSIONS[] = "supportedExtensions";
static const char EXTENSION_MESSAGE_KEY[] = "extension";
Expand All @@ -76,6 +79,7 @@ static const char SCREENREADER_KEY[] = "screenReader";

/// Document settings keys.
static const char SUPPORTS_RESIZING_KEY[] = "supportsResizing";
static const char ENVIRONMENT_VALUE_KEY[] = "environmentValues";

/// The keys used in APL event execution.
static const char ERROR_KEY[] = "error";
Expand Down Expand Up @@ -363,6 +367,17 @@ void AplCoreConnectionManager::handleConfigurationChange(const rapidjson::Value&
if (configurationChange.HasMember(SCREENREADER_KEY) && configurationChange[SCREENREADER_KEY].IsBool()) {
configChange = configChange.screenReader(configurationChange[SCREENREADER_KEY].GetBool());
}
// config change for disallowVideo
if (configurationChange.HasMember(DISALLOWVIDEO_KEY) && configurationChange[DISALLOWVIDEO_KEY].IsBool()) {
configChange = configChange.disallowVideo(configurationChange[DISALLOWVIDEO_KEY].GetBool());
}

// config change for environment value
if (configurationChange.HasMember(ENVIRONMENT_VALUE_KEY) && configurationChange[ENVIRONMENT_VALUE_KEY].IsObject()) {
for (rapidjson::Value::ConstMemberIterator iter = configurationChange[ENVIRONMENT_VALUE_KEY].MemberBegin(); iter != configurationChange[ENVIRONMENT_VALUE_KEY].MemberEnd(); ++iter){
configChange = configChange.environmentValue(iter->name.GetString(), iter->value);
}
}
updateConfigurationChange(configChange);
m_Root->configurationChange(configChange);
}
Expand Down Expand Up @@ -677,13 +692,19 @@ void AplCoreConnectionManager::handleBuild(const rapidjson::Value& message) {
std::string agentVersion = getOptionalValue(message, AGENTVERSION_KEY, "1.0");
bool allowOpenUrl = getOptionalBool(message, ALLOWOPENURL_KEY, false);
bool disallowVideo = getOptionalBool(message, DISALLOWVIDEO_KEY, false);
bool disallowDialog = getOptionalBool(message, DISALLOWDIALOG_KEY, false);
bool disallowEditText = getOptionalBool(message, DISALLOWEDITTEXT_KEY, false);

int animationQuality =
getOptionalInt(message, ANIMATIONQUALITY_KEY, apl::RootConfig::AnimationQuality::kAnimationQualityNormal);

config = apl::RootConfig()
.agent(agentName, agentVersion)
.allowOpenUrl(allowOpenUrl)
.disallowVideo(disallowVideo)
.set(apl::RootProperty::kDisallowVideo, disallowVideo)
.set(apl::RootProperty::kDisallowEditText, disallowEditText)
.set(apl::RootProperty::kDisallowDialog, disallowDialog)
.animationQuality(static_cast<apl::RootConfig::AnimationQuality>(animationQuality))
.measure(std::make_shared<AplCoreTextMeasurement>(shared_from_this(), m_aplConfiguration))
.localeMethods(std::make_shared<AplCoreLocaleMethods>(shared_from_this(), m_aplConfiguration))
Expand All @@ -710,6 +731,7 @@ void AplCoreConnectionManager::handleBuild(const rapidjson::Value& message) {
auto supportedExtensions = message[SUPPORTED_EXTENSIONS].GetArray();
// Extensions requested by the content
auto requestedExtensions = m_Content->getExtensionRequests();

for (auto& ext : supportedExtensions) {
auto uri = ext.GetString();
// If the supported extension is both requested and available, register it with the config
Expand Down Expand Up @@ -965,9 +987,9 @@ void AplCoreConnectionManager::handleMediaUpdate(const rapidjson::Value& update)
// numeric parameters are sometimes converted to null during stringification, set these to 0
const int trackIndex = getOptionalInt(state, TRACK_INDEX_KEY, 0);
const int trackCount = getOptionalInt(state, TRACK_COUNT_KEY, 0);
const int currentTime = getOptionalInt(state, CURRENT_TIME_KEY, 0);
const int duration = getOptionalInt(state, DURATION_KEY, 0);
const auto trackState = static_cast<apl::TrackState>(state[TRACK_STATE_KEY].GetInt());
const int currentTime = (int) getOptionalValue(state, CURRENT_TIME_KEY, 0);
const int duration = (int) getOptionalValue(state, DURATION_KEY, 0);
const apl::TrackState trackState = static_cast<apl::TrackState>(state[TRACK_STATE_KEY].GetInt());

apl::MediaState mediaState(
trackIndex, trackCount, currentTime, duration, state[PAUSED_KEY].GetBool(), state[ENDED_KEY].GetBool());
Expand Down
2 changes: 1 addition & 1 deletion APLClient/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ add_library(APLClient SHARED
AplClientBinding.cpp
AplConfiguration.cpp
Extensions/AplCoreExtensionManager.cpp
Extensions/AttentionSystem/AplAttentionSystemExtension.cpp
Extensions/AudioPlayer/AplAudioPlayerExtension.cpp
Extensions/AudioPlayer/AplAudioPlayerAlarmsExtension.cpp
Extensions/Backstack/AplBackstackExtension.cpp
Extensions/E2EEncryption/AplE2EEncryptionExtension.cpp
Telemetry/AplMetricsRecorder.cpp
Telemetry/AplMetricsRecorderInterface.cpp
Telemetry/DownloadMetricsEmitter.cpp
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://aws.amazon.com/apache2.0/
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/

#include "APLClient/Extensions/AttentionSystem/AplAttentionSystemExtension.h"

namespace APLClient {
namespace Extensions {
namespace AttentionSystem {

/// String to identify log entries originating from this file.
static const std::string TAG("AplAttentionSystemExtension");

static const std::map<AttentionState, std::string> attentionStateMapping = {
{AttentionState::IDLE, "IDLE"},
{AttentionState::LISTENING, "LISTENING"},
{AttentionState::THINKING, "THINKING"},
{AttentionState::SPEAKING, "SPEAKING"}
};

static const std::string SETTING_ATTENTION_SYSTEM_STATE_NAME = "attentionSystemStateName";
static const std::string PROPERTY_ATTENTION_STATE = "attentionState";
static const std::string EVENTHANDLER_ON_ATTENTION_STATE_CHANGED = "OnAttentionStateChanged";

AplAttentionSystemExtension::AplAttentionSystemExtension() {
m_attentionSystemStateName = "";
m_attentionSystemState = apl::LiveMap::create();
m_attentionSystemState->set(PROPERTY_ATTENTION_STATE, "IDLE");
}

std::string AplAttentionSystemExtension::getUri() {
return URI;
}

apl::Object AplAttentionSystemExtension::getEnvironment() {
auto env = std::make_shared<apl::ObjectMap>();

env->emplace("version", "1.0");

return apl::Object(env);
}

std::list<apl::ExtensionCommandDefinition> AplAttentionSystemExtension::getCommandDefinitions() {
return std::list<apl::ExtensionCommandDefinition>();
}

std::list<apl::ExtensionEventHandler> AplAttentionSystemExtension::getEventHandlers() {
std::list<apl::ExtensionEventHandler> extensionEventHandlers(
{
apl::ExtensionEventHandler(URI, EVENTHANDLER_ON_ATTENTION_STATE_CHANGED)
}
);
return extensionEventHandlers;
}

std::unordered_map<std::string, apl::LiveObjectPtr> AplAttentionSystemExtension::getLiveDataObjects() {
auto liveObjects = std::unordered_map<std::string, apl::LiveObjectPtr>();
if (!m_attentionSystemStateName.empty()) {
liveObjects.emplace(m_attentionSystemStateName, m_attentionSystemState);
}
return liveObjects;
}

void AplAttentionSystemExtension::applySettings(const apl::Object &settings) {
// Reset to defaults
m_attentionSystemStateName = "";
/// Apply @c apl::Content defined settings
logMessage(apl::LogLevel::kInfo, TAG, __func__, settings.toDebugString());
if (settings.isMap()) {
if (settings.has(SETTING_ATTENTION_SYSTEM_STATE_NAME)) {
m_attentionSystemStateName = settings.get(SETTING_ATTENTION_SYSTEM_STATE_NAME).getString();
}
}
}

void AplAttentionSystemExtension::onExtensionEvent(
const std::string& uri,
const std::string& name,
const apl::Object& source,
const apl::Object& params,
unsigned int event,
std::shared_ptr<AplCoreExtensionEventCallbackResultInterface> resultCallback) {
}

void AplAttentionSystemExtension::updateAttentionSystemState(const AttentionState& state) {
m_attentionSystemState->set(PROPERTY_ATTENTION_STATE, attentionStateMapping.at(state));

if (!m_eventHandler) {
logMessage(apl::LogLevel::kWarn, TAG, __func__, "No Event Handler");
return;
}

auto attentionState = apl::ObjectMap({{
PROPERTY_ATTENTION_STATE,
attentionStateMapping.at(state)
}});

m_eventHandler->invokeExtensionEventHandler(
URI,
EVENTHANDLER_ON_ATTENTION_STATE_CHANGED,
attentionState,
true
);
}
}
}
}

0 comments on commit 53ed721

Please sign in to comment.