Skip to content

Commit

Permalink
APL-CORE: March 2024 Release of APL 2024.1 compilant core engine (202…
Browse files Browse the repository at this point in the history
…4.1.0)

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
amzn-abhinvs committed Mar 12, 2024
1 parent 6ac06f5 commit b2bf611
Show file tree
Hide file tree
Showing 125 changed files with 5,630 additions and 427 deletions.
20 changes: 20 additions & 0 deletions CHANGELOG.md
@@ -1,5 +1,25 @@
# Changelog

## [2024.1]

This release adds support for version 2024.1 of the APL specification.

### Added

- Added an “onChange” handler bound variables and moved all “bind” documentation to the Bounds Variables section
- Added Visibility Change section discussing visibility change handlers. Added handleVisibilityChange component handler
- Add the Map.keys() function to Map functions
- Add pseudoLocalization to the document to enable localization-related testing of textual components
- Add maxHeight, maxWidth, minHeight, minWidth to the onConfigChange handler
- Add -experimentalHardwareAccelerationForAndroid as an experimental flag for enabling hardware acceleration for AVG rendering in Android devices as a document setting
- Add accessibilityAdjustableRange and accessibilityAdjustableValue as new properties. Add the “increment” and “decrement” standard actions
- Add 'AudioItemId' property to audioplayer extension

### Changed

- Bug fixes
- Performance improvements

## [2023.3]

This release adds support for version 2023.3 of the APL specification.
Expand Down
8 changes: 7 additions & 1 deletion apl-dev-env.sh
Expand Up @@ -128,7 +128,13 @@ function apl-check-core { # Run make for the core build with -Werror
function apl-test-core { # Run unit tests in the core build
(
apl-switch-to-build-directory build $@ && \
$CMAKE -DBUILD_TESTS=ON -DCOVERAGE=OFF .. && \
$CMAKE -DBUILD_TESTS=ON \
-DDEBUG_MEMORY_USE=ON \
-DCOVERAGE=OFF \
-DWERROR=ON \
-DDISABLE_RTTI=ON \
-DBUILD_ALEXAEXTENSIONS=ON \
-DENABLE_SCENEGRAPH=ON .. && \
make -j$APL_BUILD_PROCS && \
aplcore/unit/unittest && \
tools/unit/tools-unittest && \
Expand Down
2 changes: 1 addition & 1 deletion aplcore/include/apl/animation/easing.h
Expand Up @@ -68,7 +68,7 @@ class Easing : public ObjectData {
virtual bool operator==(const CoreEasing& other) const = 0;
virtual ~Easing() noexcept;

class ObjectType final : public PointerHolderObjectType<Easing> {
class ObjectType final : public SimplePointerHolderObjectType<Easing> {
public:
bool isCallable() const override { return true; }

Expand Down
22 changes: 19 additions & 3 deletions aplcore/include/apl/common.h
Expand Up @@ -17,6 +17,7 @@
#define _APL_COMMON_H

#include <functional>
#include <map>
#include <memory>
#include <set>

Expand Down Expand Up @@ -45,9 +46,17 @@ using apl_time_t = double;
*/
using apl_duration_t = double;

// Common definitions of shared pointer data structures. We define the XXXPtr variations
// here so they can be conveniently used from any source file.
/**
* Objects are used in a lot of places and are often passed by reference.
*/
class Object;

/**
* Common object types which are often used in shared pointers. Each of
* these objects is also declared as a shared pointer version of the form:
*
* using MyClassPtr = std::shared_ptr<MyClass>
*/
class AccessibilityAction;
class Action;
class AudioPlayer;
Expand Down Expand Up @@ -147,9 +156,16 @@ using StyleInstancePtr = std::shared_ptr<StyleInstance>;
using TextMeasurementPtr = std::shared_ptr<TextMeasurement>;
using TimersPtr = std::shared_ptr<Timers>;

// Convenience templates for creating sets of weak and strong pointers
/**
* Convenience templates for creating sets of weak and strong pointers
*/
template<class T> using SharedPtrSet = std::set<std::shared_ptr<T>, std::owner_less<std::shared_ptr<T>>>;
template<class T> using WeakPtrSet = std::set<std::weak_ptr<T>, std::owner_less<std::weak_ptr<T>>>;
template<class Key, class T> using WeakPtrMap = std::map<std::weak_ptr<Key>,
T,
std::owner_less<std::weak_ptr<Key>>,
std::allocator<std::pair<const std::weak_ptr<Key>, T>>
>;

} // namespace apl

Expand Down
2 changes: 2 additions & 0 deletions aplcore/include/apl/component/componenteventsourcewrapper.h
Expand Up @@ -41,6 +41,7 @@ class ComponentEventSourceWrapper : public ComponentEventWrapper {
Object get(const std::string& key) const override;
Object opt(const std::string& key, const Object& def) const override;
bool has(const std::string& key) const override;
std::pair<std::string, Object> keyAt(std::size_t offset) const override;
std::uint64_t size() const override;

rapidjson::Value serialize(rapidjson::Document::AllocatorType& allocator) const override;
Expand All @@ -55,6 +56,7 @@ class ComponentEventSourceWrapper : public ComponentEventWrapper {

private:
std::string mHandler;
std::string mSource;
Object mValue;
};

Expand Down
3 changes: 1 addition & 2 deletions aplcore/include/apl/component/componenteventwrapper.h
Expand Up @@ -38,10 +38,9 @@ class ComponentEventWrapper : public ObjectData {
Object get(const std::string& key) const override;
Object opt(const std::string& key, const Object& def) const override;
bool has(const std::string& key) const override;
std::pair<std::string, Object> keyAt(std::size_t offset) const override;
std::uint64_t size() const override;

const ObjectMap& getMap() const override;

ConstCoreComponentPtr getComponent() const { return mComponent.lock(); }

virtual bool operator==(const ComponentEventWrapper& rhs) const = 0;
Expand Down
8 changes: 8 additions & 0 deletions aplcore/include/apl/component/componentproperties.h
Expand Up @@ -365,6 +365,10 @@ enum PropertyKey {
kPropertyAccessibilityActions,
/// An array of assigned accessibility actions
kPropertyAccessibilityActionsAssigned,
/// Range configuration for a TouchableComponent with an adjustable role
kPropertyAccessibilityAdjustableRange,
/// Current value for a TouchableComponent with an adjustable role
kPropertyAccessibilityAdjustableValue,
/// Component accessibility label
kPropertyAccessibilityLabel,
/// ImageComponent and VectorGraphicComponent alignment (see #ImageAlign, #VectorGraphicAlign)
Expand Down Expand Up @@ -463,6 +467,8 @@ enum PropertyKey {
kPropertyFontWeight,
/// Component handler for tick
kPropertyHandleTick,
/// Component handler for visibility changes
kPropertyHandleVisibilityChange,
/// EditTextComponent highlight color behind selected text.
kPropertyHighlightColor,
/// EditTextComponent hint text,displayed when no text has been entered
Expand Down Expand Up @@ -641,6 +647,8 @@ enum PropertyKey {
kPropertyRole,
/// ImageComponent, VideoComponent, and VectorGraphicComponent scale property (see #ImageScale, #VectorGraphicScale, #VideoScale)
kPropertyScale,
/// VideoComponent screen lock
kPropertyScreenLock,
/// SequenceComponent scroll animation setting
kPropertyScrollAnimation,
/// Scrollable preserve position by absolute scroll position
Expand Down
49 changes: 39 additions & 10 deletions aplcore/include/apl/component/corecomponent.h
Expand Up @@ -370,6 +370,14 @@ class CoreComponent : public Component,
*/
size_t getEventPropertySize() const;

/**
* Return the event property at a given offset into the map. This method is used when iterating
* over the set of event properties.
* @param index The offset of the property in the map.
* @return A pair where the first value is the key and the second property is the event property value.
*/
std::pair<std::string, Object> getEventPropertyAt(size_t index) const;

/**
* The component hierarchy signature is a unique text string that represents the type
* of this component and all of the components below it in the hierarchy. This signature
Expand Down Expand Up @@ -425,6 +433,11 @@ class CoreComponent : public Component,
*/
void setVisualContextDirty();

/**
* Mark component visibility state as dirty.
*/
void setVisibilityDirty();

/**
* Convert this component into a JSON object
* @param allocator RapidJSON memory allocator
Expand Down Expand Up @@ -982,6 +995,18 @@ class CoreComponent : public Component,
*/
void markAccessibilityDirty();

/**
* Register this component for visibility calculation and tracking. No-op if component has no
* VisibilityChange handler.
*/
void registerForVisibilityTrackingIfRequired();

/**
* Deregister this component from visibility calculation. No-op if it's not registered for such
* in a first place.
*/
void deregisterFromVisibilityTracking();

#ifdef SCENEGRAPH
/**
* @return The current scene graph node.
Expand Down Expand Up @@ -1228,6 +1253,9 @@ class CoreComponent : public Component,

void processChildrenChanges();

void addDownstreamVisibilityTarget(const CoreComponentPtr& child);
void removeDownstreamVisibilityTarget(const CoreComponentPtr& child);

static std::string toStringAction(ChildChangeAction action);

protected:
Expand Down Expand Up @@ -1258,16 +1286,17 @@ class CoreComponent : public Component,
size_t index;
};

std::vector<ChildChange> mChildrenChanges;

Transform2D mGlobalToLocal;
bool mGlobalToLocalIsStale;
Point mStickyOffset;
bool mTextMeasurementHashStale;
bool mVisualHashStale;
std::string mTextMeasurementHash;
timeout_id mTickHandlerId = 0;
bool mAccessibilityDirty = false;
std::vector<ChildChange> mChildrenChanges;

Transform2D mGlobalToLocal;
bool mGlobalToLocalIsStale;
Point mStickyOffset;
bool mTextMeasurementHashStale;
bool mVisualHashStale;
std::string mTextMeasurementHash;
timeout_id mTickHandlerId = 0;
bool mAccessibilityDirty = false;
std::unique_ptr<WeakPtrSet<CoreComponent>> mAffectedByVisibilityChange;
};

} // namespace apl
Expand Down
2 changes: 2 additions & 0 deletions aplcore/include/apl/component/multichildscrollablecomponent.h
Expand Up @@ -114,6 +114,7 @@ class MultiChildScrollableComponent : public ScrollableComponent {
std::map<int, float> getChildrenVisibility(float realOpacity, const Rect &visibleRect) const override;
bool insertChild(const CoreComponentPtr& child, size_t index, bool useDirtyFlag) override;
void removeChildAfterMarkedRemoved(const CoreComponentPtr& child, size_t index, bool useDirtyFlag) override;
void releaseSelf() override;
bool getTags(rapidjson::Value& outMap, rapidjson::Document::AllocatorType& allocator) override;
virtual void layoutChildIfRequired(const CoreComponentPtr& child, size_t childIdx, bool useDirtyFlag, bool first);
void relayoutInPlace(bool useDirtyFlag, bool first);
Expand Down Expand Up @@ -180,6 +181,7 @@ class MultiChildScrollableComponent : public ScrollableComponent {
Point getPaddedScrollPosition(LayoutDirection layoutDirection) const;
void processLayoutChangesInternal(bool useDirtyFlag, bool first, bool delayed, bool needsFullReProcess);
void scheduleDelayedLayout();
double clampScrollPositionToValidValue(double scrollPosition, LayoutDirection layoutDirection, bool isHorizontal);

private:
Range mIndexesSeen;
Expand Down
5 changes: 4 additions & 1 deletion aplcore/include/apl/component/videocomponent.h
Expand Up @@ -19,14 +19,15 @@
#include "apl/component/mediacomponenttrait.h"
#include "apl/media/mediaplayerfactory.h"
#include "apl/primitives/mediastate.h"
#include "apl/utils/screenlockholder.h"

namespace apl {

class VideoComponent : public CoreComponent {
public:
static CoreComponentPtr create(const ContextPtr& context, Properties&& properties, const Path& path);
VideoComponent(const ContextPtr& context, Properties&& properties, const Path& path);
virtual ~VideoComponent() noexcept;
~VideoComponent() noexcept override;

ComponentType getType() const override { return kComponentTypeVideo; }

Expand Down Expand Up @@ -77,9 +78,11 @@ class VideoComponent : public CoreComponent {
std::shared_ptr<ObjectMap> createErrorEventProperties(int errorCode);
std::shared_ptr<ObjectMap> createReadyEventProperties();
void playerCallback(MediaPlayerEventType eventType, const MediaState& mediaState);
void updateScreenLock();

MediaPlayerPtr mMediaPlayer;
const std::string mMediaSequencer; // Internal sequencer used for onEnd/onPause/onPlay
ScreenLockHolder mScreenLock;
};


Expand Down
8 changes: 5 additions & 3 deletions aplcore/include/apl/content/aplversion.h
Expand Up @@ -39,6 +39,7 @@ class APLVersion {
kAPLVersion20231 = 0x1U << 12, /// Support version 2023.1
kAPLVersion20232 = 0x1U << 13, /// Support version 2023.2
kAPLVersion20233 = 0x1U << 14, /// Support version 2023.3
kAPLVersion20241 = 0x1U << 15, /// Support version 2024.1
kAPLVersion10to11 = kAPLVersion10 | kAPLVersion11, /// Convenience ranges from 1.0 to latest,
kAPLVersion10to12 = kAPLVersion10to11 | kAPLVersion12,
kAPLVersion10to13 = kAPLVersion10to12 | kAPLVersion13,
Expand All @@ -53,9 +54,10 @@ class APLVersion {
kAPLVersion20222to20231 = kAPLVersion20221to20222 | kAPLVersion20231,
kAPLVersion20231to20232 = kAPLVersion20222to20231 | kAPLVersion20232,
kAPLVersion20232to20233 = kAPLVersion20231to20232 | kAPLVersion20233,
kAPLVersionLatest = kAPLVersion20232to20233, /// Support the most recent engine version
kAPLVersionDefault = kAPLVersion20232to20233, /// Default value
kAPLVersionReported = kAPLVersion20233, /// Default reported version
kAPLVersion20233to20241 = kAPLVersion20232to20233 | kAPLVersion20241,
kAPLVersionLatest = kAPLVersion20233to20241, /// Support the most recent engine version
kAPLVersionDefault = kAPLVersion20233to20241, /// Default value
kAPLVersionReported = kAPLVersion20241, /// Default reported version
kAPLVersionAny = 0xffffffff, /// Support any versions in the list
};

Expand Down
3 changes: 0 additions & 3 deletions aplcore/include/apl/content/rootconfig.h
Expand Up @@ -482,9 +482,6 @@ class RootConfig {
* @deprecated Extensions should be managed via ExtensionMediator
*/
RootConfig& registerExtensionFlags(const std::string& uri, const Object& flags) {
if (mSupportedExtensions.find(uri) == mSupportedExtensions.end()) {
registerExtension(uri);
}
mExtensionFlags[uri] = flags;
return *this;
}
Expand Down
8 changes: 7 additions & 1 deletion aplcore/include/apl/datagrammar/bytecode.h
Expand Up @@ -283,8 +283,14 @@ class ByteCode : public ObjectData, public std::enable_shared_from_this<ByteCode
friend class ByteCodeOptimizer;
friend class ByteCodeEvaluator;

class ObjectType final : public EvaluableObjectType<ByteCode> {
class ObjectType final : public SimplePointerHolderObjectType<ByteCode> {
public:
bool isEvaluable() const final { return true; }

Object eval(const Object::DataHolder& dataHolder) const final {
return dataHolder.data->eval();
}

rapidjson::Value serialize(const Object::DataHolder&,
rapidjson::Document::AllocatorType& allocator) const override {
return {"COMPILED BYTE CODE", allocator};
Expand Down
2 changes: 1 addition & 1 deletion aplcore/include/apl/document/coredocumentcontext.h
Expand Up @@ -182,7 +182,7 @@ class CoreDocumentContext : public DocumentContext, public std::enable_shared_fr
/**
* @return The content
*/
const ContentPtr& content() const { return mContent; }
const ContentPtr& content() const override { return mContent; }

/**
* Create a suitable document-level data-binding context for evaluating a document-level
Expand Down
5 changes: 5 additions & 0 deletions aplcore/include/apl/document/documentcontext.h
Expand Up @@ -60,6 +60,11 @@ class DocumentContext : public NonCopyable, public Counter<DocumentContext> {
*/
virtual void clearDataSourceContextDirty() = 0;

/**
* Retrieve the document's content.
*/
virtual const ContentPtr& content() const = 0;

/**
* Retrieve datasource context as a JSON array object. This method also clears the
* datasource context dirty flag
Expand Down
2 changes: 2 additions & 0 deletions aplcore/include/apl/document/documentcontextdata.h
Expand Up @@ -38,6 +38,7 @@ class LiveDataManager;
class Sequencer;
class Styles;
class UIDManager;
class VisibilityManager;
class DataSourceConnection;
using DataSourceConnectionPtr = std::shared_ptr<DataSourceConnection>;

Expand Down Expand Up @@ -101,6 +102,7 @@ class DocumentContextData : public ContextData, public std::enable_shared_from_t
MediaPlayerFactory& mediaPlayerFactory() const;
UIDManager& uniqueIdManager() const { return *mUniqueIdManager; }
DependantManager& dependantManager() const;
VisibilityManager& visibilityManager() const;

const YGConfigRef& ygconfig() const;
const SessionPtr& session() const override { return mSession; }
Expand Down

0 comments on commit b2bf611

Please sign in to comment.