Skip to content

Commit

Permalink
Version 1.11 alexa-client-sdk
Browse files Browse the repository at this point in the history
Changes in this update:

**Enhancements**

* Added support for the new Alexa [DoNotDisturb](https://developer.amazon.com/docs/alexa-voice-service/donotdisturb.html) interface, which enables users to toggle the do not disturb (DND) function on their Alexa built-in products.
* The SDK now supports [Opus](https://opus-codec.org/license/) encoding, which is optional. To enable Opus, you must [set the CMake flag to `-DOPUS=ON`](https://github.com/alexa/avs-device-sdk/wiki/Build-Options#Opus-encoding), and include the [libopus library](https://github.com/alexa/avs-device-sdk/wiki/Dependencies#core-dependencies) dependency in your build.
* The MediaPlayer reference implementation has been expanded to support the SAMPLE-AES and AES-128 encryption methods for HLS streaming.
  * AES-128 encryption is dependent on libcrypto, which is part of the required openSSL library, and is enabled by default.
  * To enable [SAMPLE-AES](https://github.com/alexa/avs-device-sdk/wiki/Dependencies#core-dependencies/Enable-SAMPLE-AES-decryption) encryption, you must set the `-DSAMPLE_AES=ON` in your CMake command, and include the [FFMPEG](https://github.com/alexa/avs-device-sdk/wiki/Dependencies#core-dependencies/Enable-SAMPLE-AES-decryption) library dependency in your build.
* A new configuration for [deviceSettings](https://github.com/alexa/avs-device-sdk/blob/v1.11.0/Integration/AlexaClientSDKConfig.json#L59) has been added.This configuration allows you to specify the location of the device settings database.
* Added locale support for es-MX.

**Bug Fixes**

* Fixed an issue where music wouldn't resume playback in the Android app.
* Now all equalizer capabilities are fully disabled when equalizer is turned off in configuration file. Previously, devices were unconditionally required to provide support for equalizer in order to run the SDK.
* [Issue 1106](alexa#1106) - Fixed an issue in which the `CBLAuthDelegate` wasn't using the correct timeout during request refresh.
* [Issue 1128](alexa#1128) - Fixed an issue in which the `AudioPlayer` instance persisted at shutdown, due to a shared dependency with the `ProgressTimer`.
* Fixed in issue that occurred when a connection to streaming content was interrupted, the SDK did not attempt to resume the connection, and appeared to assume that the content had been fully downloaded. This triggered the next track to be played, assuming it was a playlist.
* [Issue 1040](alexa#1040) - Fixed an issue where alarms would continue to play after user barge-in.

**Known Issues**

* `PlaylistParser` and `IterativePlaylistParser` generate two HTTP requests (one to fetch the content type, and one to fetch the audio data) for each audio stream played.
* Music playback history isn't being displayed in the Alexa app for certain account and device types.
* On GCC 8+, issues related to `-Wclass-memaccess` will trigger warnings. However, this won't cause the build to fail, and these warnings can be ignored.
* In order to use Bluetooth source and sink PulseAudio, you must manually load and unload PulseAudio modules after the SDK starts.
* The `ACL` may encounter issues if audio attachments are received but not consumed.
* `SpeechSynthesizerState` currently uses `GAINING_FOCUS` and `LOSING_FOCUS` as a workaround for handling intermediate state. These states may be removed in a future release.
* The Alexa app doesn't always indicate when a device is successfully connected via Bluetooth.
* Connecting a product to streaming media via Bluetooth will sometimes stop media playback within the source application. Resuming playback through the source application or toggling next/previous will correct playback.
* When a source device is streaming silence via Bluetooth, the Alexa app indicates that audio content is streaming.
* The Bluetooth agent assumes that the Bluetooth adapter is always connected to a power source. Disconnecting from a power source during operation is not yet supported.
* On some products, interrupted Bluetooth playback may not resume if other content is locally streamed.
* `make integration` is currently not available for Android. In order to run integration tests on Android, you'll need to manually upload the test binary file along with any input file. At that point, the adb can be used to run the integration tests.
* On Raspberry Pi running Android Things with HDMI output audio, beginning of speech is truncated when Alexa responds to user TTS.
* When the sample app is restarted and network connection is lost, alerts don't play.
* When network connection is lost, lost connection status is not returned via local Text-to Speech (TTS).
  • Loading branch information
scotthea-amazon committed Dec 19, 2018
1 parent 178bcb1 commit 451e605
Show file tree
Hide file tree
Showing 180 changed files with 12,114 additions and 1,242 deletions.
71 changes: 64 additions & 7 deletions ADSL/include/ADSL/DirectiveProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,13 @@
#ifndef ALEXA_CLIENT_SDK_ADSL_INCLUDE_ADSL_DIRECTIVEPROCESSOR_H_
#define ALEXA_CLIENT_SDK_ADSL_INCLUDE_ADSL_DIRECTIVEPROCESSOR_H_

#include <array>
#include <condition_variable>
#include <deque>
#include <functional>
#include <memory>
#include <mutex>
#include <set>
#include <string>
#include <thread>
#include <unordered_map>
Expand Down Expand Up @@ -122,6 +125,9 @@ class DirectiveProcessor {
*/
using ProcessorHandle = unsigned int;

/// The type of the handling queue items.
using DirectiveAndPolicy = std::pair<std::shared_ptr<avsCommon::avs::AVSDirective>, avsCommon::avs::BlockingPolicy>;

/**
* Implementation of @c DirectiveHandlerResultInterface that forwards the completion / failure status
* to the @c DirectiveProcessor from which it originated.
Expand Down Expand Up @@ -189,14 +195,14 @@ class DirectiveProcessor {
bool processCancelingQueueLocked(std::unique_lock<std::mutex>& lock);

/**
* Process (handle) the next @c AVSDirective in @c m_handlingQueue.
* Process (handle) all the items in @c m_handlingQueue which are not blocked.
* @note This method must only be called by threads that have acquired @c m_mutex.
*
* @param lock A @c unique_lock on m_mutex from the callers context, allowing this method to release
* (and re-acquire) the lock around callbacks that need to be invoked.
* @return Whether an @c AVSDirective from m_handlingQueue was processed.
*/
bool handleDirectiveLocked(std::unique_lock<std::mutex>& lock);
bool handleQueuedDirectivesLocked(std::unique_lock<std::mutex>& lock);

/**
* Set the current @c dialogRequestId. This cancels the processing of any @c AVSDirectives with a non-empty
Expand All @@ -223,6 +229,47 @@ class DirectiveProcessor {
*/
void queueAllDirectivesForCancellationLocked();

/**
* Save a pointer to the given directive as a directive which is being handled.
* A pointer to the directive is saved per @c BlockingPolicy::Channel used by the policy.
* This pointer can be used later to indicate which @c BlockingPolicy::Channel
* is blocked by which @c AVSDirective.
*
* @param directive The @c AVSDirective being handled.
* @param policy The @c BlockingPolicy assiciated with the given directive.
*/
void setDirectiveBeingHandledLocked(
const std::shared_ptr<avsCommon::avs::AVSDirective>& directive,
const avsCommon::avs::BlockingPolicy policy);

/**
* Clear the pointer to the directive being handled.
* @note See the above @c saveDirectiveBeingHandledLocked comment
* for further explanation.
*
* @param policy The @c BlockingPolicy with which the saved directive is associated.
*/
void clearDirectiveBeingHandledLocked(const avsCommon::avs::BlockingPolicy policy);

/**
* Clear the pointer to the directive being handled.
*
* @note See the above @c saveDirectiveBeingHandledLocked comment
* for further explanation.
* @param shouldClear Matcher to indicate which saved directive we should free.
*
* @return An @c std::set of the freed directives.
*/
std::set<std::shared_ptr<avsCommon::avs::AVSDirective>> clearDirectiveBeingHandledLocked(
std::function<bool(const std::shared_ptr<avsCommon::avs::AVSDirective>&)> shouldClear);

/**
* Get the next unblocked @c DirectiveAndPolicy form the handling queue.
*
* @return An @c std::iterator to the next unblocked @c DirectiveAndPolicy.
*/
std::deque<DirectiveAndPolicy>::iterator getNextUnblockedDirectiveLocked();

/// Handle value identifying this instance.
int m_handle;

Expand All @@ -247,11 +294,12 @@ class DirectiveProcessor {
/// The directive (if any) for which a preHandleDirective() call is in progress.
std::shared_ptr<avsCommon::avs::AVSDirective> m_directiveBeingPreHandled;

/// Queue of @c AVSDirectives waiting to be handled.
std::deque<std::shared_ptr<avsCommon::avs::AVSDirective>> m_handlingQueue;

/// Whether @c handleDirective() has been called for the directive at the @c front() of @c m_handlingQueue.
bool m_isHandlingDirective;
/**
* Queue of @c AVSDirectives waiting to be handled.
* @Note: A queue per channel would be more efficient, but as we don't expect more than few
* directives on the queue, we prefer simplicity.
*/
std::deque<DirectiveAndPolicy> m_handlingQueue;

/// Condition variable used to wake @c processingLoop() when it is waiting.
std::condition_variable m_wakeProcessingLoop;
Expand All @@ -273,6 +321,15 @@ class DirectiveProcessor {

/// Next available @c ProcessorHandle value.
static ProcessorHandle m_nextProcessorHandle;

/**
* The directives which are being handled on various channels. A directive is consider as 'being handled'
* while the @c handleDirective method of the directive handler is running, and, if the directive is blocking
* until directive handling has been completed. i.e. @c DirectiveHandlerResult::setCompleted
* or @c DirectiveHandlerResult::setFailed have been called.
*/
std::array<std::shared_ptr<avsCommon::avs::AVSDirective>, avsCommon::avs::BlockingPolicy::Medium::COUNT>
m_directivesBeingHandled;
};

} // namespace adsl
Expand Down
39 changes: 23 additions & 16 deletions ADSL/include/ADSL/DirectiveRouter.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#ifndef ALEXA_CLIENT_SDK_ADSL_INCLUDE_ADSL_DIRECTIVEROUTER_H_
#define ALEXA_CLIENT_SDK_ADSL_INCLUDE_ADSL_DIRECTIVEROUTER_H_

#include <map>
#include <set>
#include <unordered_map>

Expand Down Expand Up @@ -63,15 +64,6 @@ class DirectiveRouter : public avsCommon::utils::RequiresShutdown {
*/
bool handleDirectiveImmediately(std::shared_ptr<avsCommon::avs::AVSDirective> directive);

/**
* Check if the directive handler's blocking policy is HANDLE_IMMEDIATELY for this directive, if so invoke @c
* handleDirectiveImmediately() on the handler registered for the given @c AVSDirective.
*
* @param directive The directive to be handled immediately.
* @return Whether or not the handler was invoked.
*/
bool handleDirectiveWithPolicyHandleImmediately(std::shared_ptr<avsCommon::avs::AVSDirective> directive);

/**
* Invoke @c preHandleDirective() on the handler registered for the given @c AVSDirective.
*
Expand All @@ -88,14 +80,10 @@ class DirectiveRouter : public avsCommon::utils::RequiresShutdown {
* Invoke @c handleDirective() on the handler registered for the given @c AVSDirective.
*
* @param directive The directive to be handled.
* @param[out] policyOut If this method returns @c true, @c policyOut is set to the @c BlockingPolicy value that
* was configured when @c handleDirective() was called.
* @return @c true if the the registered handler returned @c true. @c false if there was no registered handler
* or the registered handler returned @c false (indicating that the directive was not recognized.
*/
bool handleDirective(
std::shared_ptr<avsCommon::avs::AVSDirective> directive,
avsCommon::avs::BlockingPolicy* policyOut);
bool handleDirective(const std::shared_ptr<avsCommon::avs::AVSDirective>& directive);

/**
* Invoke cancelDirective() on the handler registered for the given @c AVSDirective.
Expand All @@ -105,6 +93,14 @@ class DirectiveRouter : public avsCommon::utils::RequiresShutdown {
*/
bool cancelDirective(std::shared_ptr<avsCommon::avs::AVSDirective> directive);

/**
* Get the policy associated with the given directive.
*
* @param directive The directive for which the policy is required.
* @return The corresponding @c BlockingPolicy value for the directive.
*/
avsCommon::avs::BlockingPolicy getPolicy(const std::shared_ptr<avsCommon::avs::AVSDirective>& directive);

private:
void doShutdown() override;

Expand Down Expand Up @@ -150,13 +146,24 @@ class DirectiveRouter : public avsCommon::utils::RequiresShutdown {
};

/**
* Look up the @c HandlerAndPolicy value for the specified @c AVSDirective.
* Look up the configured @c HandlerAndPolicy value for the specified @c AVSDirective.
* @note The calling thread must have already acquired @c m_mutex.
*
* @param directive The directive to look up a value for.
* @return The corresponding @c HandlerAndPolicy value for the specified directive.
*/
avsCommon::avs::HandlerAndPolicy getHandlerAndPolicyLocked(std::shared_ptr<avsCommon::avs::AVSDirective> directive);
avsCommon::avs::HandlerAndPolicy getdHandlerAndPolicyLocked(
const std::shared_ptr<avsCommon::avs::AVSDirective>& directive);

/**
* Get the @c DirectiveHandler for this directive.
* @note The calling thread must have already acquired @c m_mutex.
*
* @param directive The @c AVSDirective for which we're looking for handler.
* @return The directive handler for success. @c nullptr in failure.
*/
std::shared_ptr<avsCommon::sdkInterfaces::DirectiveHandlerInterface> getHandlerLocked(
std::shared_ptr<avsCommon::avs::AVSDirective> directive);

/**
* Increment the reference count for the specified handler.
Expand Down
Loading

0 comments on commit 451e605

Please sign in to comment.