2017-10-30 22:14:38 +00:00
|
|
|
/*
|
Version 1.12 alexa-client-sdk
Changes in this update:
**Enhancements**
* Support was added for the `fr_CA` locale.
* The Executor has been optimized to run a single thread when there are active job in the queue, and to remain idle when there are not active jobs.
* An additional parameter of `alertType` has been added to the Alerts capability agent. This will allow observers of alerts to know the type of alert being delivered.
* Support for programmatic unload and load of PulseAudio Bluetooth modules was added. To enable this feature, there is a [new CMake option](https://github.com/alexa/avs-device-sdk/wiki/CMake-parameters#bluetooth): `BLUETOOTH_BLUEZ_PULSEAUDIO_OVERRIDE_ENDPOINTS`. Note that [libpulse-dev is a required dependency](https://github.com/alexa/avs-device-sdk/wiki/Dependencies#bluetooth) of this feature.
* An observer interface was added for when an active Bluetooth device connects and disconnects.
* The `BluetoothDeviceManagerInterface` instantiation was moved from `DefaultClient` to `SampleApp` to allow applications to override it.
* The `MediaPlayerInterface` now supports repeating playback of URL sources.
* The Kitt.AI wake word engine (WWE) is now compatible with GCC5+.
* Stop of ongoing alerts, management of MessageObservers, and management of CallStateObservers have been exposed through DefaultClient.
**Bug Fixes**
* [Issue 953](https://github.com/alexa/avs-device-sdk/issues/953) - The `MediaPlayerInterface` requirement that callbacks not be made upon a callers thread has been removed.
* [Issue 1136](https://github.com/alexa/avs-device-sdk/issues/1136) - Added a missing default virtual destructor.
* [Issue 1140](https://github.com/alexa/avs-device-sdk/issues/1140) - Fixed an issue where DND states were not synchronized to the AVS cloud after device reset.
* [Issue 1143](https://github.com/alexa/avs-device-sdk/issues/1143) - Fixed an issue in which the SpeechSynthesizer couldn't enter a sleeping state.
* [Issue 1183](https://github.com/alexa/avs-device-sdk/issues/1183) - Fixed an issue where alarm is not sounding for certain timezones
* Changing an alert's volume from the Alexa app now works when an alert is playing.
* Added missing shutdown handling for ContentDecrypter to prevent the `Stop` command from triggering a crash when SAMPLE-AES encrypted content was streaming.
* Fixed a bug where if the Notifications database is empty, due to a crash or corruption, the SDK initialization process enters an infinite loop when it retries to get context from the Notifications capability agent.
* Fixed a race condition that caused `AlertsRenderer` observers to miss notification that an alert has been completed.
**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.
* Android error ("libDefaultClient.so" not found) can be resolved by upgrading to ADB version 1.0.40
* When network connection is lost, lost connection status is not returned via local TTS.
* `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 text-to-speech (TTS).
* When the sample app is restarted and network connection is lost, Reminder TTS does not play. Instead, the default alarm tone will play twice.
2019-02-26 00:45:37 +00:00
|
|
|
* Copyright 2017-2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
2017-10-30 22:14:38 +00:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
|
|
|
|
/// @file TemplateRuntimeTest
|
2018-03-09 00:55:39 +00:00
|
|
|
#include <future>
|
2017-10-30 22:14:38 +00:00
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
#include <gmock/gmock.h>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include <rapidjson/document.h>
|
|
|
|
|
|
|
|
#include <AVSCommon/AVS/Attachment/MockAttachmentManager.h>
|
|
|
|
#include <AVSCommon/SDKInterfaces/AudioPlayerInterface.h>
|
|
|
|
#include <AVSCommon/SDKInterfaces/AudioPlayerObserverInterface.h>
|
|
|
|
#include <AVSCommon/SDKInterfaces/MockDirectiveHandlerResult.h>
|
|
|
|
#include <AVSCommon/SDKInterfaces/MockExceptionEncounteredSender.h>
|
2018-03-09 00:55:39 +00:00
|
|
|
#include <AVSCommon/SDKInterfaces/MockFocusManager.h>
|
2017-10-30 22:14:38 +00:00
|
|
|
#include <AVSCommon/SDKInterfaces/TemplateRuntimeObserverInterface.h>
|
|
|
|
#include <AVSCommon/Utils/JSON/JSONUtils.h>
|
|
|
|
#include <AVSCommon/Utils/Memory/Memory.h>
|
|
|
|
|
|
|
|
#include "TemplateRuntime/TemplateRuntime.h"
|
|
|
|
|
|
|
|
namespace alexaClientSDK {
|
|
|
|
namespace capabilityAgents {
|
|
|
|
namespace templateRuntime {
|
|
|
|
namespace test {
|
|
|
|
|
|
|
|
using namespace avsCommon::avs;
|
|
|
|
using namespace avsCommon::avs::attachment::test;
|
|
|
|
using namespace avsCommon::sdkInterfaces;
|
|
|
|
using namespace avsCommon::sdkInterfaces::test;
|
|
|
|
using namespace avsCommon::utils::memory;
|
|
|
|
using namespace rapidjson;
|
|
|
|
using namespace ::testing;
|
|
|
|
|
|
|
|
/// Timeout when waiting for futures to be set.
|
|
|
|
static std::chrono::milliseconds TIMEOUT(1000);
|
|
|
|
|
2018-03-09 00:55:39 +00:00
|
|
|
/// Timeout when waiting for clearTemplateCard.
|
|
|
|
static std::chrono::milliseconds TEMPLATE_TIMEOUT(5000);
|
|
|
|
|
Version 1.12 alexa-client-sdk
Changes in this update:
**Enhancements**
* Support was added for the `fr_CA` locale.
* The Executor has been optimized to run a single thread when there are active job in the queue, and to remain idle when there are not active jobs.
* An additional parameter of `alertType` has been added to the Alerts capability agent. This will allow observers of alerts to know the type of alert being delivered.
* Support for programmatic unload and load of PulseAudio Bluetooth modules was added. To enable this feature, there is a [new CMake option](https://github.com/alexa/avs-device-sdk/wiki/CMake-parameters#bluetooth): `BLUETOOTH_BLUEZ_PULSEAUDIO_OVERRIDE_ENDPOINTS`. Note that [libpulse-dev is a required dependency](https://github.com/alexa/avs-device-sdk/wiki/Dependencies#bluetooth) of this feature.
* An observer interface was added for when an active Bluetooth device connects and disconnects.
* The `BluetoothDeviceManagerInterface` instantiation was moved from `DefaultClient` to `SampleApp` to allow applications to override it.
* The `MediaPlayerInterface` now supports repeating playback of URL sources.
* The Kitt.AI wake word engine (WWE) is now compatible with GCC5+.
* Stop of ongoing alerts, management of MessageObservers, and management of CallStateObservers have been exposed through DefaultClient.
**Bug Fixes**
* [Issue 953](https://github.com/alexa/avs-device-sdk/issues/953) - The `MediaPlayerInterface` requirement that callbacks not be made upon a callers thread has been removed.
* [Issue 1136](https://github.com/alexa/avs-device-sdk/issues/1136) - Added a missing default virtual destructor.
* [Issue 1140](https://github.com/alexa/avs-device-sdk/issues/1140) - Fixed an issue where DND states were not synchronized to the AVS cloud after device reset.
* [Issue 1143](https://github.com/alexa/avs-device-sdk/issues/1143) - Fixed an issue in which the SpeechSynthesizer couldn't enter a sleeping state.
* [Issue 1183](https://github.com/alexa/avs-device-sdk/issues/1183) - Fixed an issue where alarm is not sounding for certain timezones
* Changing an alert's volume from the Alexa app now works when an alert is playing.
* Added missing shutdown handling for ContentDecrypter to prevent the `Stop` command from triggering a crash when SAMPLE-AES encrypted content was streaming.
* Fixed a bug where if the Notifications database is empty, due to a crash or corruption, the SDK initialization process enters an infinite loop when it retries to get context from the Notifications capability agent.
* Fixed a race condition that caused `AlertsRenderer` observers to miss notification that an alert has been completed.
**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.
* Android error ("libDefaultClient.so" not found) can be resolved by upgrading to ADB version 1.0.40
* When network connection is lost, lost connection status is not returned via local TTS.
* `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 text-to-speech (TTS).
* When the sample app is restarted and network connection is lost, Reminder TTS does not play. Instead, the default alarm tone will play twice.
2019-02-26 00:45:37 +00:00
|
|
|
/// Timeout when waiting for clearTemplateCard not called.
|
|
|
|
static std::chrono::milliseconds TEMPLATE_NOT_CLEAR_TIMEOUT(2500);
|
|
|
|
|
2018-03-09 00:55:39 +00:00
|
|
|
/// Timeout when waiting for clearTemplateCard.
|
|
|
|
static std::chrono::milliseconds PLAYER_FINISHED_TIMEOUT(5000);
|
|
|
|
|
2017-10-30 22:14:38 +00:00
|
|
|
/// The namespace for this capability agent.
|
|
|
|
static const std::string NAMESPACE{"TemplateRuntime"};
|
|
|
|
|
|
|
|
/// An unknown directive signature.
|
|
|
|
static const std::string UNKNOWN_DIRECTIVE{"Unknown"};
|
|
|
|
|
|
|
|
/// The RenderTemplate directive signature.
|
|
|
|
static const NamespaceAndName TEMPLATE{NAMESPACE, "RenderTemplate"};
|
|
|
|
|
|
|
|
/// The RenderPlayerInfo directive signature.
|
|
|
|
static const NamespaceAndName PLAYER_INFO{NAMESPACE, "RenderPlayerInfo"};
|
|
|
|
|
|
|
|
/// The @c MessageId identifer.
|
|
|
|
static const std::string MESSAGE_ID("messageId");
|
|
|
|
|
|
|
|
/// An audioItemId for the RenderPlayerInfo directive.
|
|
|
|
static const std::string AUDIO_ITEM_ID("AudioItemId abcdefgh");
|
|
|
|
|
|
|
|
/// An audioItemId without a corresponding RenderPlayerInfo directive.
|
|
|
|
static const std::string AUDIO_ITEM_ID_1("AudioItemId 12345678");
|
|
|
|
|
|
|
|
/// A RenderTemplate directive payload.
|
|
|
|
// clang-format off
|
|
|
|
static const std::string TEMPLATE_PAYLOAD = "{"
|
|
|
|
"\"token\":\"TOKEN1\","
|
|
|
|
"\"type\":\"BodyTemplate1\","
|
|
|
|
"\"title\":{"
|
|
|
|
"\"mainTitle\":\"MAIN_TITLE\","
|
|
|
|
"\"subTitle\":\"SUB_TITLE\""
|
|
|
|
"}"
|
|
|
|
"}";
|
|
|
|
// clang-format on
|
|
|
|
|
|
|
|
/// A RenderPlayerInfo directive payload.
|
|
|
|
// clang-format off
|
|
|
|
static const std::string PLAYERINFO_PAYLOAD = "{"
|
|
|
|
"\"audioItemId\":\"" + AUDIO_ITEM_ID + "\","
|
|
|
|
"\"content\":{"
|
|
|
|
"\"title\":\"TITLE\","
|
|
|
|
"\"header\":\"HEADER\""
|
|
|
|
"}"
|
|
|
|
"}";
|
|
|
|
// clang-format on
|
|
|
|
|
|
|
|
/// A malformed RenderPlayerInfo directive payload.
|
|
|
|
// clang-format off
|
|
|
|
static const std::string MALFORM_PLAYERINFO_PAYLOAD = "{"
|
|
|
|
"\"audioItemId\"::::\"" + AUDIO_ITEM_ID + "\","
|
|
|
|
"\"content\":{{{{"
|
|
|
|
"\"title\":\"TITLE\","
|
|
|
|
"\"header\":\"HEADER\""
|
|
|
|
"}"
|
|
|
|
"}";
|
|
|
|
// clang-format on
|
|
|
|
|
|
|
|
class MockAudioPlayer : public AudioPlayerInterface {
|
|
|
|
public:
|
|
|
|
MOCK_METHOD1(addObserver, void(std::shared_ptr<avsCommon::sdkInterfaces::AudioPlayerObserverInterface> observer));
|
|
|
|
MOCK_METHOD1(
|
|
|
|
removeObserver,
|
|
|
|
void(std::shared_ptr<avsCommon::sdkInterfaces::AudioPlayerObserverInterface> observer));
|
|
|
|
MOCK_METHOD0(getAudioItemOffset, std::chrono::milliseconds());
|
|
|
|
};
|
|
|
|
|
|
|
|
class MockGui : public TemplateRuntimeObserverInterface {
|
|
|
|
public:
|
2018-03-09 00:55:39 +00:00
|
|
|
MOCK_METHOD2(renderTemplateCard, void(const std::string& jsonPayload, avsCommon::avs::FocusState focusState));
|
|
|
|
MOCK_METHOD0(clearTemplateCard, void());
|
|
|
|
MOCK_METHOD3(
|
2017-10-30 22:14:38 +00:00
|
|
|
renderPlayerInfoCard,
|
2018-03-09 00:55:39 +00:00
|
|
|
void(
|
|
|
|
const std::string& jsonPayload,
|
|
|
|
TemplateRuntimeObserverInterface::AudioPlayerInfo audioPlayerInfo,
|
|
|
|
avsCommon::avs::FocusState focusState));
|
|
|
|
MOCK_METHOD0(clearPlayerInfoCard, void());
|
2017-10-30 22:14:38 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/// Test harness for @c TemplateRuntime class.
|
|
|
|
class TemplateRuntimeTest : public ::testing::Test {
|
|
|
|
public:
|
|
|
|
/// Set up the test harness for running a test.
|
|
|
|
void SetUp() override;
|
|
|
|
|
|
|
|
/// Clean up the test harness after running a test.
|
|
|
|
void TearDown() override;
|
|
|
|
|
|
|
|
/// Function to set the promise and wake @c m_wakeSetCompleteFuture.
|
|
|
|
void wakeOnSetCompleted();
|
|
|
|
|
|
|
|
/// Function to set the promise and wake @c m_wakeRenderTemplateCardFuture.
|
|
|
|
void wakeOnRenderTemplateCard();
|
|
|
|
|
|
|
|
/// Function to set the promise and wake @c m_wakeRenderPlayerInfoCardFuture.
|
|
|
|
void wakeOnRenderPlayerInfoCard();
|
|
|
|
|
2018-03-09 00:55:39 +00:00
|
|
|
/// Function to set the promise and wake @c m_wakeClearTemplateCardFuture.
|
|
|
|
void wakeOnClearTemplateCard();
|
|
|
|
|
|
|
|
/// Function to set the promise and wake @c m_wakeClearPlayerInfoCardFuture.
|
|
|
|
void wakeOnClearPlayerInfoCard();
|
|
|
|
|
|
|
|
/// Function to set the promise and wake @c m_wakeReleaseChannelFuture.
|
|
|
|
void wakeOnReleaseChannel();
|
|
|
|
|
2017-10-30 22:14:38 +00:00
|
|
|
/// A constructor which initializes the promises and futures needed for the test class.
|
|
|
|
TemplateRuntimeTest() :
|
|
|
|
m_wakeSetCompletedPromise{},
|
|
|
|
m_wakeSetCompletedFuture{m_wakeSetCompletedPromise.get_future()},
|
|
|
|
m_wakeRenderTemplateCardPromise{},
|
|
|
|
m_wakeRenderTemplateCardFuture{m_wakeRenderTemplateCardPromise.get_future()},
|
|
|
|
m_wakeRenderPlayerInfoCardPromise{},
|
2018-03-09 00:55:39 +00:00
|
|
|
m_wakeRenderPlayerInfoCardFuture{m_wakeRenderPlayerInfoCardPromise.get_future()},
|
|
|
|
m_wakeClearTemplateCardPromise{},
|
|
|
|
m_wakeClearTemplateCardFuture{m_wakeClearTemplateCardPromise.get_future()},
|
|
|
|
m_wakeClearPlayerInfoCardPromise{},
|
|
|
|
m_wakeClearPlayerInfoCardFuture{m_wakeClearPlayerInfoCardPromise.get_future()},
|
|
|
|
m_wakeReleaseChannelPromise{},
|
|
|
|
m_wakeReleaseChannelFuture{m_wakeReleaseChannelPromise.get_future()} {
|
2017-10-30 22:14:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
/// Promise to synchronize directive handling through setCompleted.
|
|
|
|
std::promise<void> m_wakeSetCompletedPromise;
|
|
|
|
|
|
|
|
/// Future to synchronize directive handling through setCompleted.
|
|
|
|
std::future<void> m_wakeSetCompletedFuture;
|
|
|
|
|
|
|
|
/// Promise to synchronize directive handling with RenderTemplateCard callback.
|
|
|
|
std::promise<void> m_wakeRenderTemplateCardPromise;
|
|
|
|
|
|
|
|
/// Future to synchronize directive handling with RenderTemplateCard callback.
|
|
|
|
std::future<void> m_wakeRenderTemplateCardFuture;
|
|
|
|
|
|
|
|
/// Promise to synchronize directive handling with RenderPlayerInfoCard callback.
|
|
|
|
std::promise<void> m_wakeRenderPlayerInfoCardPromise;
|
|
|
|
|
|
|
|
/// Future to synchronize directive handling with RenderPlayerInfoCard callback.
|
|
|
|
std::future<void> m_wakeRenderPlayerInfoCardFuture;
|
|
|
|
|
2018-03-09 00:55:39 +00:00
|
|
|
/// Promise to synchronize ClearTemplateCard callback.
|
|
|
|
std::promise<void> m_wakeClearTemplateCardPromise;
|
|
|
|
|
|
|
|
/// Future to synchronize ClearTemplateCard callback.
|
|
|
|
std::future<void> m_wakeClearTemplateCardFuture;
|
|
|
|
|
|
|
|
/// Promise to synchronize ClearPlayerInfoCard callback.
|
|
|
|
std::promise<void> m_wakeClearPlayerInfoCardPromise;
|
|
|
|
|
|
|
|
/// Future to synchronize ClearPlayerInfoCard callback.
|
|
|
|
std::future<void> m_wakeClearPlayerInfoCardFuture;
|
|
|
|
|
|
|
|
/// Promise to synchronize releaseChannel calls.
|
|
|
|
std::promise<void> m_wakeReleaseChannelPromise;
|
|
|
|
|
|
|
|
/// Future to synchronize releaseChannel calls.
|
|
|
|
std::future<void> m_wakeReleaseChannelFuture;
|
|
|
|
|
2017-10-30 22:14:38 +00:00
|
|
|
/// A nice mock for the AudioPlayerInterface calls.
|
|
|
|
std::shared_ptr<NiceMock<MockAudioPlayer>> m_mockAudioPlayerInterface;
|
|
|
|
|
|
|
|
/// A strict mock that allows the test to strictly monitor the exceptions being sent.
|
|
|
|
std::shared_ptr<StrictMock<MockExceptionEncounteredSender>> m_mockExceptionSender;
|
|
|
|
|
|
|
|
/// A strict mock that allows the test to strictly monitor the handling of directives.
|
|
|
|
std::unique_ptr<StrictMock<MockDirectiveHandlerResult>> m_mockDirectiveHandlerResult;
|
|
|
|
|
2018-03-09 00:55:39 +00:00
|
|
|
/// @c FocusManager to request focus to the Visual channel.
|
|
|
|
std::shared_ptr<MockFocusManager> m_mockFocusManager;
|
|
|
|
|
2017-10-30 22:14:38 +00:00
|
|
|
/// A strict mock to allow testing of the observer callback.
|
|
|
|
std::shared_ptr<StrictMock<MockGui>> m_mockGui;
|
|
|
|
|
|
|
|
/// A pointer to an instance of the TemplateRuntime that will be instantiated per test.
|
|
|
|
std::shared_ptr<TemplateRuntime> m_templateRuntime;
|
|
|
|
};
|
|
|
|
|
|
|
|
void TemplateRuntimeTest::SetUp() {
|
|
|
|
m_mockExceptionSender = std::make_shared<StrictMock<MockExceptionEncounteredSender>>();
|
|
|
|
m_mockDirectiveHandlerResult = make_unique<StrictMock<MockDirectiveHandlerResult>>();
|
2018-03-09 00:55:39 +00:00
|
|
|
m_mockFocusManager = std::make_shared<NiceMock<MockFocusManager>>();
|
2017-10-30 22:14:38 +00:00
|
|
|
m_mockAudioPlayerInterface = std::make_shared<NiceMock<MockAudioPlayer>>();
|
|
|
|
m_mockGui = std::make_shared<StrictMock<MockGui>>();
|
2018-03-09 00:55:39 +00:00
|
|
|
m_templateRuntime = TemplateRuntime::create(m_mockAudioPlayerInterface, m_mockFocusManager, m_mockExceptionSender);
|
|
|
|
m_templateRuntime->addObserver(m_mockGui);
|
|
|
|
|
|
|
|
ON_CALL(*m_mockFocusManager, acquireChannel(_, _, _)).WillByDefault(InvokeWithoutArgs([this] {
|
|
|
|
m_templateRuntime->onFocusChanged(avsCommon::avs::FocusState::FOREGROUND);
|
|
|
|
return true;
|
|
|
|
}));
|
|
|
|
|
|
|
|
ON_CALL(*m_mockFocusManager, releaseChannel(_, _)).WillByDefault(InvokeWithoutArgs([this] {
|
|
|
|
auto releaseChannelSuccess = std::make_shared<std::promise<bool>>();
|
|
|
|
std::future<bool> returnValue = releaseChannelSuccess->get_future();
|
|
|
|
m_templateRuntime->onFocusChanged(avsCommon::avs::FocusState::NONE);
|
|
|
|
releaseChannelSuccess->set_value(true);
|
|
|
|
return returnValue;
|
|
|
|
}));
|
2017-10-30 22:14:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void TemplateRuntimeTest::TearDown() {
|
|
|
|
if (m_templateRuntime) {
|
|
|
|
m_templateRuntime->shutdown();
|
|
|
|
m_templateRuntime.reset();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void TemplateRuntimeTest::wakeOnSetCompleted() {
|
|
|
|
m_wakeSetCompletedPromise.set_value();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TemplateRuntimeTest::wakeOnRenderTemplateCard() {
|
|
|
|
m_wakeRenderTemplateCardPromise.set_value();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TemplateRuntimeTest::wakeOnRenderPlayerInfoCard() {
|
|
|
|
m_wakeRenderPlayerInfoCardPromise.set_value();
|
|
|
|
}
|
|
|
|
|
2018-03-09 00:55:39 +00:00
|
|
|
void TemplateRuntimeTest::wakeOnClearTemplateCard() {
|
|
|
|
m_wakeClearTemplateCardPromise.set_value();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TemplateRuntimeTest::wakeOnClearPlayerInfoCard() {
|
|
|
|
m_wakeClearPlayerInfoCardPromise.set_value();
|
|
|
|
}
|
|
|
|
|
|
|
|
void TemplateRuntimeTest::wakeOnReleaseChannel() {
|
|
|
|
m_wakeReleaseChannelPromise.set_value();
|
|
|
|
}
|
|
|
|
|
2017-10-30 22:14:38 +00:00
|
|
|
/**
|
|
|
|
* Tests creating the TemplateRuntime with a null audioPlayerInterface.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(TemplateRuntimeTest, test_nullAudioPlayerInterface) {
|
2018-03-09 00:55:39 +00:00
|
|
|
auto templateRuntime = TemplateRuntime::create(nullptr, m_mockFocusManager, m_mockExceptionSender);
|
|
|
|
ASSERT_EQ(templateRuntime, nullptr);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests creating the TemplateRuntime with a null focusManagerInterface.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(TemplateRuntimeTest, test_nullFocusManagerInterface) {
|
2018-03-09 00:55:39 +00:00
|
|
|
auto templateRuntime = TemplateRuntime::create(m_mockAudioPlayerInterface, nullptr, m_mockExceptionSender);
|
|
|
|
ASSERT_EQ(templateRuntime, nullptr);
|
2017-10-30 22:14:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests creating the TemplateRuntime with a null exceptionSender.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(TemplateRuntimeTest, test_nullExceptionSender) {
|
2018-03-09 00:55:39 +00:00
|
|
|
auto templateRuntime = TemplateRuntime::create(m_mockAudioPlayerInterface, m_mockFocusManager, nullptr);
|
|
|
|
ASSERT_EQ(templateRuntime, nullptr);
|
2017-10-30 22:14:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests that the TemplateRuntime successfully add itself with the AudioPlayer at constructor time, and
|
|
|
|
* successfully remove itself with the AudioPlayer during shutdown.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(TemplateRuntimeTest, test_audioPlayerAddRemoveObserver) {
|
2018-03-09 00:55:39 +00:00
|
|
|
auto mockAudioPlayerInterface = std::make_shared<NiceMock<MockAudioPlayer>>();
|
|
|
|
auto mockExceptionSender = std::make_shared<StrictMock<MockExceptionEncounteredSender>>();
|
|
|
|
auto mockFocusManager = std::make_shared<NiceMock<MockFocusManager>>();
|
|
|
|
EXPECT_CALL(*mockAudioPlayerInterface, addObserver(NotNull())).Times(Exactly(1));
|
|
|
|
EXPECT_CALL(*mockAudioPlayerInterface, removeObserver(NotNull())).Times(Exactly(1));
|
|
|
|
auto templateRuntime = TemplateRuntime::create(mockAudioPlayerInterface, mockFocusManager, mockExceptionSender);
|
|
|
|
templateRuntime->shutdown();
|
2017-10-30 22:14:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests unknown Directive. Expect that the sendExceptionEncountered and setFailed will be called.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(TemplateRuntimeTest, test_unknownDirective) {
|
2017-10-30 22:14:38 +00:00
|
|
|
// Create Directive.
|
|
|
|
auto attachmentManager = std::make_shared<StrictMock<MockAttachmentManager>>();
|
|
|
|
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(NAMESPACE, UNKNOWN_DIRECTIVE, MESSAGE_ID);
|
|
|
|
std::shared_ptr<AVSDirective> directive = AVSDirective::create("", avsMessageHeader, "", attachmentManager, "");
|
|
|
|
|
|
|
|
EXPECT_CALL(*m_mockExceptionSender, sendExceptionEncountered(_, _, _)).Times(Exactly(1));
|
|
|
|
EXPECT_CALL(*m_mockDirectiveHandlerResult, setFailed(_))
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnSetCompleted));
|
|
|
|
|
|
|
|
m_templateRuntime->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
|
Version 1.12 alexa-client-sdk
Changes in this update:
**Enhancements**
* Support was added for the `fr_CA` locale.
* The Executor has been optimized to run a single thread when there are active job in the queue, and to remain idle when there are not active jobs.
* An additional parameter of `alertType` has been added to the Alerts capability agent. This will allow observers of alerts to know the type of alert being delivered.
* Support for programmatic unload and load of PulseAudio Bluetooth modules was added. To enable this feature, there is a [new CMake option](https://github.com/alexa/avs-device-sdk/wiki/CMake-parameters#bluetooth): `BLUETOOTH_BLUEZ_PULSEAUDIO_OVERRIDE_ENDPOINTS`. Note that [libpulse-dev is a required dependency](https://github.com/alexa/avs-device-sdk/wiki/Dependencies#bluetooth) of this feature.
* An observer interface was added for when an active Bluetooth device connects and disconnects.
* The `BluetoothDeviceManagerInterface` instantiation was moved from `DefaultClient` to `SampleApp` to allow applications to override it.
* The `MediaPlayerInterface` now supports repeating playback of URL sources.
* The Kitt.AI wake word engine (WWE) is now compatible with GCC5+.
* Stop of ongoing alerts, management of MessageObservers, and management of CallStateObservers have been exposed through DefaultClient.
**Bug Fixes**
* [Issue 953](https://github.com/alexa/avs-device-sdk/issues/953) - The `MediaPlayerInterface` requirement that callbacks not be made upon a callers thread has been removed.
* [Issue 1136](https://github.com/alexa/avs-device-sdk/issues/1136) - Added a missing default virtual destructor.
* [Issue 1140](https://github.com/alexa/avs-device-sdk/issues/1140) - Fixed an issue where DND states were not synchronized to the AVS cloud after device reset.
* [Issue 1143](https://github.com/alexa/avs-device-sdk/issues/1143) - Fixed an issue in which the SpeechSynthesizer couldn't enter a sleeping state.
* [Issue 1183](https://github.com/alexa/avs-device-sdk/issues/1183) - Fixed an issue where alarm is not sounding for certain timezones
* Changing an alert's volume from the Alexa app now works when an alert is playing.
* Added missing shutdown handling for ContentDecrypter to prevent the `Stop` command from triggering a crash when SAMPLE-AES encrypted content was streaming.
* Fixed a bug where if the Notifications database is empty, due to a crash or corruption, the SDK initialization process enters an infinite loop when it retries to get context from the Notifications capability agent.
* Fixed a race condition that caused `AlertsRenderer` observers to miss notification that an alert has been completed.
**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.
* Android error ("libDefaultClient.so" not found) can be resolved by upgrading to ADB version 1.0.40
* When network connection is lost, lost connection status is not returned via local TTS.
* `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 text-to-speech (TTS).
* When the sample app is restarted and network connection is lost, Reminder TTS does not play. Instead, the default alarm tone will play twice.
2019-02-26 00:45:37 +00:00
|
|
|
m_templateRuntime->CapabilityAgent::handleDirective(MESSAGE_ID);
|
2017-10-30 22:14:38 +00:00
|
|
|
m_wakeSetCompletedFuture.wait_for(TIMEOUT);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2018-03-09 00:55:39 +00:00
|
|
|
* Tests RenderTemplate Directive. Expect that the renderTemplateCard callback will be called and clearTemplateCard will
|
|
|
|
* be called after 2s after DialogUXState is changed to IDLE state.
|
2017-10-30 22:14:38 +00:00
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(TemplateRuntimeTest, testSlow_renderTemplateDirective) {
|
2017-10-30 22:14:38 +00:00
|
|
|
// Create Directive.
|
|
|
|
auto attachmentManager = std::make_shared<StrictMock<MockAttachmentManager>>();
|
|
|
|
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(TEMPLATE.nameSpace, TEMPLATE.name, MESSAGE_ID);
|
|
|
|
std::shared_ptr<AVSDirective> directive =
|
|
|
|
AVSDirective::create("", avsMessageHeader, TEMPLATE_PAYLOAD, attachmentManager, "");
|
|
|
|
|
2018-03-09 00:55:39 +00:00
|
|
|
EXPECT_CALL(*m_mockGui, renderTemplateCard(TEMPLATE_PAYLOAD, _))
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnRenderTemplateCard));
|
2017-10-30 22:14:38 +00:00
|
|
|
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted())
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnSetCompleted));
|
2018-03-09 00:55:39 +00:00
|
|
|
EXPECT_CALL(*m_mockGui, clearTemplateCard())
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnClearTemplateCard));
|
2017-10-30 22:14:38 +00:00
|
|
|
|
|
|
|
m_templateRuntime->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
|
|
|
|
m_templateRuntime->CapabilityAgent::handleDirective(MESSAGE_ID);
|
|
|
|
m_wakeSetCompletedFuture.wait_for(TIMEOUT);
|
2018-03-09 00:55:39 +00:00
|
|
|
m_wakeRenderTemplateCardFuture.wait_for(TIMEOUT);
|
|
|
|
m_templateRuntime->onDialogUXStateChanged(
|
|
|
|
avsCommon::sdkInterfaces::DialogUXStateObserverInterface::DialogUXState::IDLE);
|
|
|
|
m_wakeClearTemplateCardFuture.wait_for(TEMPLATE_TIMEOUT);
|
2017-10-30 22:14:38 +00:00
|
|
|
}
|
|
|
|
|
Version 1.12 alexa-client-sdk
Changes in this update:
**Enhancements**
* Support was added for the `fr_CA` locale.
* The Executor has been optimized to run a single thread when there are active job in the queue, and to remain idle when there are not active jobs.
* An additional parameter of `alertType` has been added to the Alerts capability agent. This will allow observers of alerts to know the type of alert being delivered.
* Support for programmatic unload and load of PulseAudio Bluetooth modules was added. To enable this feature, there is a [new CMake option](https://github.com/alexa/avs-device-sdk/wiki/CMake-parameters#bluetooth): `BLUETOOTH_BLUEZ_PULSEAUDIO_OVERRIDE_ENDPOINTS`. Note that [libpulse-dev is a required dependency](https://github.com/alexa/avs-device-sdk/wiki/Dependencies#bluetooth) of this feature.
* An observer interface was added for when an active Bluetooth device connects and disconnects.
* The `BluetoothDeviceManagerInterface` instantiation was moved from `DefaultClient` to `SampleApp` to allow applications to override it.
* The `MediaPlayerInterface` now supports repeating playback of URL sources.
* The Kitt.AI wake word engine (WWE) is now compatible with GCC5+.
* Stop of ongoing alerts, management of MessageObservers, and management of CallStateObservers have been exposed through DefaultClient.
**Bug Fixes**
* [Issue 953](https://github.com/alexa/avs-device-sdk/issues/953) - The `MediaPlayerInterface` requirement that callbacks not be made upon a callers thread has been removed.
* [Issue 1136](https://github.com/alexa/avs-device-sdk/issues/1136) - Added a missing default virtual destructor.
* [Issue 1140](https://github.com/alexa/avs-device-sdk/issues/1140) - Fixed an issue where DND states were not synchronized to the AVS cloud after device reset.
* [Issue 1143](https://github.com/alexa/avs-device-sdk/issues/1143) - Fixed an issue in which the SpeechSynthesizer couldn't enter a sleeping state.
* [Issue 1183](https://github.com/alexa/avs-device-sdk/issues/1183) - Fixed an issue where alarm is not sounding for certain timezones
* Changing an alert's volume from the Alexa app now works when an alert is playing.
* Added missing shutdown handling for ContentDecrypter to prevent the `Stop` command from triggering a crash when SAMPLE-AES encrypted content was streaming.
* Fixed a bug where if the Notifications database is empty, due to a crash or corruption, the SDK initialization process enters an infinite loop when it retries to get context from the Notifications capability agent.
* Fixed a race condition that caused `AlertsRenderer` observers to miss notification that an alert has been completed.
**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.
* Android error ("libDefaultClient.so" not found) can be resolved by upgrading to ADB version 1.0.40
* When network connection is lost, lost connection status is not returned via local TTS.
* `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 text-to-speech (TTS).
* When the sample app is restarted and network connection is lost, Reminder TTS does not play. Instead, the default alarm tone will play twice.
2019-02-26 00:45:37 +00:00
|
|
|
/**
|
|
|
|
* Tests RenderTemplate Directive. Expect that the renderTemplateCard callback will be called and clearTemplateCard will
|
|
|
|
* not be called if DialogUXState goes to IDLE state and then goes EXPECTING and SPEAKING state.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(
|
|
|
|
TemplateRuntimeTest,
|
|
|
|
testRenderTemplateDirectiveWillNotClearCardAfterGoingToExpectingStateAfterGoingToIDLESlowTest) {
|
Version 1.12 alexa-client-sdk
Changes in this update:
**Enhancements**
* Support was added for the `fr_CA` locale.
* The Executor has been optimized to run a single thread when there are active job in the queue, and to remain idle when there are not active jobs.
* An additional parameter of `alertType` has been added to the Alerts capability agent. This will allow observers of alerts to know the type of alert being delivered.
* Support for programmatic unload and load of PulseAudio Bluetooth modules was added. To enable this feature, there is a [new CMake option](https://github.com/alexa/avs-device-sdk/wiki/CMake-parameters#bluetooth): `BLUETOOTH_BLUEZ_PULSEAUDIO_OVERRIDE_ENDPOINTS`. Note that [libpulse-dev is a required dependency](https://github.com/alexa/avs-device-sdk/wiki/Dependencies#bluetooth) of this feature.
* An observer interface was added for when an active Bluetooth device connects and disconnects.
* The `BluetoothDeviceManagerInterface` instantiation was moved from `DefaultClient` to `SampleApp` to allow applications to override it.
* The `MediaPlayerInterface` now supports repeating playback of URL sources.
* The Kitt.AI wake word engine (WWE) is now compatible with GCC5+.
* Stop of ongoing alerts, management of MessageObservers, and management of CallStateObservers have been exposed through DefaultClient.
**Bug Fixes**
* [Issue 953](https://github.com/alexa/avs-device-sdk/issues/953) - The `MediaPlayerInterface` requirement that callbacks not be made upon a callers thread has been removed.
* [Issue 1136](https://github.com/alexa/avs-device-sdk/issues/1136) - Added a missing default virtual destructor.
* [Issue 1140](https://github.com/alexa/avs-device-sdk/issues/1140) - Fixed an issue where DND states were not synchronized to the AVS cloud after device reset.
* [Issue 1143](https://github.com/alexa/avs-device-sdk/issues/1143) - Fixed an issue in which the SpeechSynthesizer couldn't enter a sleeping state.
* [Issue 1183](https://github.com/alexa/avs-device-sdk/issues/1183) - Fixed an issue where alarm is not sounding for certain timezones
* Changing an alert's volume from the Alexa app now works when an alert is playing.
* Added missing shutdown handling for ContentDecrypter to prevent the `Stop` command from triggering a crash when SAMPLE-AES encrypted content was streaming.
* Fixed a bug where if the Notifications database is empty, due to a crash or corruption, the SDK initialization process enters an infinite loop when it retries to get context from the Notifications capability agent.
* Fixed a race condition that caused `AlertsRenderer` observers to miss notification that an alert has been completed.
**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.
* Android error ("libDefaultClient.so" not found) can be resolved by upgrading to ADB version 1.0.40
* When network connection is lost, lost connection status is not returned via local TTS.
* `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 text-to-speech (TTS).
* When the sample app is restarted and network connection is lost, Reminder TTS does not play. Instead, the default alarm tone will play twice.
2019-02-26 00:45:37 +00:00
|
|
|
// Create Directive.
|
|
|
|
auto attachmentManager = std::make_shared<StrictMock<MockAttachmentManager>>();
|
|
|
|
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(TEMPLATE.nameSpace, TEMPLATE.name, MESSAGE_ID);
|
|
|
|
std::shared_ptr<AVSDirective> directive =
|
|
|
|
AVSDirective::create("", avsMessageHeader, TEMPLATE_PAYLOAD, attachmentManager, "");
|
|
|
|
|
|
|
|
EXPECT_CALL(*m_mockGui, renderTemplateCard(TEMPLATE_PAYLOAD, _))
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnRenderTemplateCard));
|
|
|
|
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted())
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnSetCompleted));
|
|
|
|
EXPECT_CALL(*m_mockGui, clearTemplateCard()).Times(Exactly(0));
|
|
|
|
|
|
|
|
m_templateRuntime->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
|
|
|
|
m_templateRuntime->CapabilityAgent::handleDirective(MESSAGE_ID);
|
|
|
|
m_wakeSetCompletedFuture.wait_for(TIMEOUT);
|
|
|
|
m_wakeRenderTemplateCardFuture.wait_for(TIMEOUT);
|
|
|
|
|
|
|
|
// first test IDLE->EXPECTING transition
|
|
|
|
m_templateRuntime->onDialogUXStateChanged(
|
|
|
|
avsCommon::sdkInterfaces::DialogUXStateObserverInterface::DialogUXState::IDLE);
|
|
|
|
m_templateRuntime->onDialogUXStateChanged(
|
|
|
|
avsCommon::sdkInterfaces::DialogUXStateObserverInterface::DialogUXState::EXPECTING);
|
|
|
|
EXPECT_EQ(m_wakeClearTemplateCardFuture.wait_for(TEMPLATE_NOT_CLEAR_TIMEOUT), std::future_status::timeout);
|
|
|
|
|
|
|
|
// now test IDLE->SPEAKING transition
|
|
|
|
m_templateRuntime->onDialogUXStateChanged(
|
|
|
|
avsCommon::sdkInterfaces::DialogUXStateObserverInterface::DialogUXState::IDLE);
|
|
|
|
m_templateRuntime->onDialogUXStateChanged(
|
|
|
|
avsCommon::sdkInterfaces::DialogUXStateObserverInterface::DialogUXState::SPEAKING);
|
|
|
|
EXPECT_EQ(m_wakeClearTemplateCardFuture.wait_for(TEMPLATE_NOT_CLEAR_TIMEOUT), std::future_status::timeout);
|
|
|
|
}
|
|
|
|
|
2017-10-30 22:14:38 +00:00
|
|
|
/**
|
|
|
|
* Tests RenderTemplate Directive using the handleDirectiveImmediately. Expect that the renderTemplateCard
|
|
|
|
* callback will be called.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(TemplateRuntimeTest, test_handleDirectiveImmediately) {
|
2017-10-30 22:14:38 +00:00
|
|
|
// Create Directive.
|
|
|
|
auto attachmentManager = std::make_shared<StrictMock<MockAttachmentManager>>();
|
|
|
|
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(TEMPLATE.nameSpace, TEMPLATE.name, MESSAGE_ID);
|
|
|
|
std::shared_ptr<AVSDirective> directive =
|
|
|
|
AVSDirective::create("", avsMessageHeader, TEMPLATE_PAYLOAD, attachmentManager, "");
|
|
|
|
|
2018-03-09 00:55:39 +00:00
|
|
|
EXPECT_CALL(*m_mockGui, renderTemplateCard(TEMPLATE_PAYLOAD, _))
|
2017-10-30 22:14:38 +00:00
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnRenderTemplateCard));
|
|
|
|
|
|
|
|
m_templateRuntime->handleDirectiveImmediately(directive);
|
|
|
|
m_wakeRenderTemplateCardFuture.wait_for(TIMEOUT);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests RenderTemplate Directive received before the corresponding AudioPlayer call. Expect
|
2018-03-09 00:55:39 +00:00
|
|
|
* that the renderTemplateCard callback will be called and clearPlayerInfoCard will be called after 2s after Audio State
|
|
|
|
* is changed to FINISHED state.
|
2017-10-30 22:14:38 +00:00
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(TemplateRuntimeTest, testSlow_renderPlayerInfoDirectiveBefore) {
|
2017-10-30 22:14:38 +00:00
|
|
|
// Create Directive.
|
|
|
|
auto attachmentManager = std::make_shared<StrictMock<MockAttachmentManager>>();
|
|
|
|
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(PLAYER_INFO.nameSpace, PLAYER_INFO.name, MESSAGE_ID);
|
|
|
|
std::shared_ptr<AVSDirective> directive =
|
|
|
|
AVSDirective::create("", avsMessageHeader, PLAYERINFO_PAYLOAD, attachmentManager, "");
|
|
|
|
|
|
|
|
::testing::InSequence s;
|
|
|
|
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted())
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnSetCompleted));
|
2018-03-09 00:55:39 +00:00
|
|
|
EXPECT_CALL(*m_mockGui, renderTemplateCard(_, _)).Times(Exactly(0));
|
2017-10-30 22:14:38 +00:00
|
|
|
|
|
|
|
// do not expect renderPlayerInfo card call until AudioPlayer notify with the correct audioItemId
|
2018-03-09 00:55:39 +00:00
|
|
|
EXPECT_CALL(*m_mockGui, renderPlayerInfoCard(_, _, _)).Times(Exactly(0));
|
2017-10-30 22:14:38 +00:00
|
|
|
|
|
|
|
m_templateRuntime->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
|
|
|
|
m_templateRuntime->CapabilityAgent::handleDirective(MESSAGE_ID);
|
|
|
|
m_wakeSetCompletedFuture.wait_for(TIMEOUT);
|
|
|
|
|
2018-03-09 00:55:39 +00:00
|
|
|
EXPECT_CALL(*m_mockGui, renderPlayerInfoCard(PLAYERINFO_PAYLOAD, _, _))
|
|
|
|
.Times(Exactly(2))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnRenderPlayerInfoCard))
|
|
|
|
.WillOnce(InvokeWithoutArgs([] {}));
|
2017-10-30 22:14:38 +00:00
|
|
|
|
|
|
|
AudioPlayerObserverInterface::Context context;
|
|
|
|
context.audioItemId = AUDIO_ITEM_ID;
|
|
|
|
context.offset = TIMEOUT;
|
|
|
|
m_templateRuntime->onPlayerActivityChanged(avsCommon::avs::PlayerActivity::PLAYING, context);
|
|
|
|
|
|
|
|
m_wakeRenderPlayerInfoCardFuture.wait_for(TIMEOUT);
|
2018-03-09 00:55:39 +00:00
|
|
|
|
|
|
|
EXPECT_CALL(*m_mockGui, clearPlayerInfoCard())
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnClearPlayerInfoCard));
|
|
|
|
|
|
|
|
m_templateRuntime->onPlayerActivityChanged(avsCommon::avs::PlayerActivity::FINISHED, context);
|
|
|
|
m_wakeClearPlayerInfoCardFuture.wait_for(PLAYER_FINISHED_TIMEOUT);
|
2017-10-30 22:14:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests RenderTemplate Directive received after the corresponding AudioPlayer call. Expect
|
|
|
|
* that the renderTemplateCard callback will be called.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(TemplateRuntimeTest, test_renderPlayerInfoDirectiveAfter) {
|
2017-10-30 22:14:38 +00:00
|
|
|
// Create Directive.
|
|
|
|
auto attachmentManager = std::make_shared<StrictMock<MockAttachmentManager>>();
|
|
|
|
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(PLAYER_INFO.nameSpace, PLAYER_INFO.name, MESSAGE_ID);
|
|
|
|
std::shared_ptr<AVSDirective> directive =
|
|
|
|
AVSDirective::create("", avsMessageHeader, PLAYERINFO_PAYLOAD, attachmentManager, "");
|
|
|
|
|
2018-03-09 00:55:39 +00:00
|
|
|
EXPECT_CALL(*m_mockGui, renderPlayerInfoCard(PLAYERINFO_PAYLOAD, _, _))
|
2017-10-30 22:14:38 +00:00
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnRenderPlayerInfoCard));
|
|
|
|
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted())
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnSetCompleted));
|
|
|
|
|
|
|
|
AudioPlayerObserverInterface::Context context;
|
|
|
|
context.audioItemId = AUDIO_ITEM_ID;
|
|
|
|
context.offset = TIMEOUT;
|
|
|
|
m_templateRuntime->onPlayerActivityChanged(avsCommon::avs::PlayerActivity::PLAYING, context);
|
|
|
|
m_templateRuntime->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
|
|
|
|
m_templateRuntime->CapabilityAgent::handleDirective(MESSAGE_ID);
|
|
|
|
|
|
|
|
m_wakeRenderPlayerInfoCardFuture.wait_for(TIMEOUT);
|
|
|
|
m_wakeSetCompletedFuture.wait_for(TIMEOUT);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests RenderTemplate Directive received without an audioItemId. Expect that the
|
|
|
|
* sendExceptionEncountered and setFailed will be called.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(TemplateRuntimeTest, test_renderPlayerInfoDirectiveWithoutAudioItemId) {
|
2017-10-30 22:14:38 +00:00
|
|
|
// Create Directive.
|
|
|
|
auto attachmentManager = std::make_shared<StrictMock<MockAttachmentManager>>();
|
|
|
|
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(PLAYER_INFO.nameSpace, PLAYER_INFO.name, MESSAGE_ID);
|
|
|
|
std::shared_ptr<AVSDirective> directive =
|
|
|
|
AVSDirective::create("", avsMessageHeader, TEMPLATE_PAYLOAD, attachmentManager, "");
|
|
|
|
|
|
|
|
EXPECT_CALL(*m_mockExceptionSender, sendExceptionEncountered(_, _, _)).Times(Exactly(1));
|
|
|
|
EXPECT_CALL(*m_mockDirectiveHandlerResult, setFailed(_))
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnSetCompleted));
|
|
|
|
|
|
|
|
m_templateRuntime->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
|
Version 1.12 alexa-client-sdk
Changes in this update:
**Enhancements**
* Support was added for the `fr_CA` locale.
* The Executor has been optimized to run a single thread when there are active job in the queue, and to remain idle when there are not active jobs.
* An additional parameter of `alertType` has been added to the Alerts capability agent. This will allow observers of alerts to know the type of alert being delivered.
* Support for programmatic unload and load of PulseAudio Bluetooth modules was added. To enable this feature, there is a [new CMake option](https://github.com/alexa/avs-device-sdk/wiki/CMake-parameters#bluetooth): `BLUETOOTH_BLUEZ_PULSEAUDIO_OVERRIDE_ENDPOINTS`. Note that [libpulse-dev is a required dependency](https://github.com/alexa/avs-device-sdk/wiki/Dependencies#bluetooth) of this feature.
* An observer interface was added for when an active Bluetooth device connects and disconnects.
* The `BluetoothDeviceManagerInterface` instantiation was moved from `DefaultClient` to `SampleApp` to allow applications to override it.
* The `MediaPlayerInterface` now supports repeating playback of URL sources.
* The Kitt.AI wake word engine (WWE) is now compatible with GCC5+.
* Stop of ongoing alerts, management of MessageObservers, and management of CallStateObservers have been exposed through DefaultClient.
**Bug Fixes**
* [Issue 953](https://github.com/alexa/avs-device-sdk/issues/953) - The `MediaPlayerInterface` requirement that callbacks not be made upon a callers thread has been removed.
* [Issue 1136](https://github.com/alexa/avs-device-sdk/issues/1136) - Added a missing default virtual destructor.
* [Issue 1140](https://github.com/alexa/avs-device-sdk/issues/1140) - Fixed an issue where DND states were not synchronized to the AVS cloud after device reset.
* [Issue 1143](https://github.com/alexa/avs-device-sdk/issues/1143) - Fixed an issue in which the SpeechSynthesizer couldn't enter a sleeping state.
* [Issue 1183](https://github.com/alexa/avs-device-sdk/issues/1183) - Fixed an issue where alarm is not sounding for certain timezones
* Changing an alert's volume from the Alexa app now works when an alert is playing.
* Added missing shutdown handling for ContentDecrypter to prevent the `Stop` command from triggering a crash when SAMPLE-AES encrypted content was streaming.
* Fixed a bug where if the Notifications database is empty, due to a crash or corruption, the SDK initialization process enters an infinite loop when it retries to get context from the Notifications capability agent.
* Fixed a race condition that caused `AlertsRenderer` observers to miss notification that an alert has been completed.
**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.
* Android error ("libDefaultClient.so" not found) can be resolved by upgrading to ADB version 1.0.40
* When network connection is lost, lost connection status is not returned via local TTS.
* `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 text-to-speech (TTS).
* When the sample app is restarted and network connection is lost, Reminder TTS does not play. Instead, the default alarm tone will play twice.
2019-02-26 00:45:37 +00:00
|
|
|
m_templateRuntime->CapabilityAgent::handleDirective(MESSAGE_ID);
|
2017-10-30 22:14:38 +00:00
|
|
|
m_wakeSetCompletedFuture.wait_for(TIMEOUT);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests when a malformed RenderTemplate Directive is received. Expect that the
|
|
|
|
* sendExceptionEncountered and setFailed will be called.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(TemplateRuntimeTest, test_malformedRenderPlayerInfoDirective) {
|
2017-10-30 22:14:38 +00:00
|
|
|
// Create Directive.
|
|
|
|
auto attachmentManager = std::make_shared<StrictMock<MockAttachmentManager>>();
|
|
|
|
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(PLAYER_INFO.nameSpace, PLAYER_INFO.name, MESSAGE_ID);
|
|
|
|
std::shared_ptr<AVSDirective> directive =
|
|
|
|
AVSDirective::create("", avsMessageHeader, MALFORM_PLAYERINFO_PAYLOAD, attachmentManager, "");
|
|
|
|
|
|
|
|
EXPECT_CALL(*m_mockExceptionSender, sendExceptionEncountered(_, _, _)).Times(Exactly(1));
|
|
|
|
EXPECT_CALL(*m_mockDirectiveHandlerResult, setFailed(_))
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnSetCompleted));
|
|
|
|
|
|
|
|
m_templateRuntime->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
|
Version 1.12 alexa-client-sdk
Changes in this update:
**Enhancements**
* Support was added for the `fr_CA` locale.
* The Executor has been optimized to run a single thread when there are active job in the queue, and to remain idle when there are not active jobs.
* An additional parameter of `alertType` has been added to the Alerts capability agent. This will allow observers of alerts to know the type of alert being delivered.
* Support for programmatic unload and load of PulseAudio Bluetooth modules was added. To enable this feature, there is a [new CMake option](https://github.com/alexa/avs-device-sdk/wiki/CMake-parameters#bluetooth): `BLUETOOTH_BLUEZ_PULSEAUDIO_OVERRIDE_ENDPOINTS`. Note that [libpulse-dev is a required dependency](https://github.com/alexa/avs-device-sdk/wiki/Dependencies#bluetooth) of this feature.
* An observer interface was added for when an active Bluetooth device connects and disconnects.
* The `BluetoothDeviceManagerInterface` instantiation was moved from `DefaultClient` to `SampleApp` to allow applications to override it.
* The `MediaPlayerInterface` now supports repeating playback of URL sources.
* The Kitt.AI wake word engine (WWE) is now compatible with GCC5+.
* Stop of ongoing alerts, management of MessageObservers, and management of CallStateObservers have been exposed through DefaultClient.
**Bug Fixes**
* [Issue 953](https://github.com/alexa/avs-device-sdk/issues/953) - The `MediaPlayerInterface` requirement that callbacks not be made upon a callers thread has been removed.
* [Issue 1136](https://github.com/alexa/avs-device-sdk/issues/1136) - Added a missing default virtual destructor.
* [Issue 1140](https://github.com/alexa/avs-device-sdk/issues/1140) - Fixed an issue where DND states were not synchronized to the AVS cloud after device reset.
* [Issue 1143](https://github.com/alexa/avs-device-sdk/issues/1143) - Fixed an issue in which the SpeechSynthesizer couldn't enter a sleeping state.
* [Issue 1183](https://github.com/alexa/avs-device-sdk/issues/1183) - Fixed an issue where alarm is not sounding for certain timezones
* Changing an alert's volume from the Alexa app now works when an alert is playing.
* Added missing shutdown handling for ContentDecrypter to prevent the `Stop` command from triggering a crash when SAMPLE-AES encrypted content was streaming.
* Fixed a bug where if the Notifications database is empty, due to a crash or corruption, the SDK initialization process enters an infinite loop when it retries to get context from the Notifications capability agent.
* Fixed a race condition that caused `AlertsRenderer` observers to miss notification that an alert has been completed.
**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.
* Android error ("libDefaultClient.so" not found) can be resolved by upgrading to ADB version 1.0.40
* When network connection is lost, lost connection status is not returned via local TTS.
* `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 text-to-speech (TTS).
* When the sample app is restarted and network connection is lost, Reminder TTS does not play. Instead, the default alarm tone will play twice.
2019-02-26 00:45:37 +00:00
|
|
|
m_templateRuntime->CapabilityAgent::handleDirective(MESSAGE_ID);
|
2017-10-30 22:14:38 +00:00
|
|
|
m_wakeSetCompletedFuture.wait_for(TIMEOUT);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests AudioPlayer notified the handling of AUDIO_ITEM_ID_1, and then RenderTemplate Directive with
|
|
|
|
* AUDIO_ITEM_ID is received. Expect that the renderTemplateCard callback will not be called until
|
|
|
|
* the AudioPlayer notified the handling of AUDIO_ITEM_ID later.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(TemplateRuntimeTest, test_renderPlayerInfoDirectiveDifferentAudioItemId) {
|
2017-10-30 22:14:38 +00:00
|
|
|
// Create Directive.
|
|
|
|
auto attachmentManager = std::make_shared<StrictMock<MockAttachmentManager>>();
|
|
|
|
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(PLAYER_INFO.nameSpace, PLAYER_INFO.name, MESSAGE_ID);
|
|
|
|
std::shared_ptr<AVSDirective> directive =
|
|
|
|
AVSDirective::create("", avsMessageHeader, PLAYERINFO_PAYLOAD, attachmentManager, "");
|
|
|
|
|
2018-03-09 00:55:39 +00:00
|
|
|
EXPECT_CALL(*m_mockGui, renderPlayerInfoCard(PLAYERINFO_PAYLOAD, _, _)).Times(Exactly(0));
|
2017-10-30 22:14:38 +00:00
|
|
|
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted())
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnSetCompleted));
|
|
|
|
|
|
|
|
AudioPlayerObserverInterface::Context context;
|
|
|
|
context.audioItemId = AUDIO_ITEM_ID_1;
|
|
|
|
context.offset = TIMEOUT;
|
|
|
|
m_templateRuntime->onPlayerActivityChanged(avsCommon::avs::PlayerActivity::PLAYING, context);
|
|
|
|
m_templateRuntime->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
|
|
|
|
m_templateRuntime->CapabilityAgent::handleDirective(MESSAGE_ID);
|
|
|
|
m_wakeSetCompletedFuture.wait_for(TIMEOUT);
|
|
|
|
|
2018-03-09 00:55:39 +00:00
|
|
|
EXPECT_CALL(*m_mockGui, renderPlayerInfoCard(PLAYERINFO_PAYLOAD, _, _))
|
2017-10-30 22:14:38 +00:00
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnRenderPlayerInfoCard));
|
|
|
|
|
|
|
|
context.audioItemId = AUDIO_ITEM_ID;
|
|
|
|
m_templateRuntime->onPlayerActivityChanged(avsCommon::avs::PlayerActivity::PLAYING, context);
|
|
|
|
|
|
|
|
m_wakeRenderPlayerInfoCardFuture.wait_for(TIMEOUT);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests AudioPlayer callbacks will trigger the correct renderPlayerInfoCard callbacks. Expect
|
|
|
|
* the payload, audioPlayerState and offset to match to the ones passed in by the
|
|
|
|
* AudioPlayerObserverInterface.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(TemplateRuntimeTest, test_renderPlayerInfoDirectiveAudioStateUpdate) {
|
2017-10-30 22:14:38 +00:00
|
|
|
// Create Directive.
|
|
|
|
auto attachmentManager = std::make_shared<StrictMock<MockAttachmentManager>>();
|
|
|
|
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(PLAYER_INFO.nameSpace, PLAYER_INFO.name, MESSAGE_ID);
|
|
|
|
std::shared_ptr<AVSDirective> directive =
|
|
|
|
AVSDirective::create("", avsMessageHeader, PLAYERINFO_PAYLOAD, attachmentManager, "");
|
|
|
|
|
|
|
|
::testing::InSequence s;
|
|
|
|
// Send a directive first to TemplateRuntime
|
|
|
|
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted())
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnSetCompleted));
|
|
|
|
m_templateRuntime->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
|
|
|
|
m_templateRuntime->CapabilityAgent::handleDirective(MESSAGE_ID);
|
|
|
|
m_wakeSetCompletedFuture.wait_for(TIMEOUT);
|
|
|
|
|
|
|
|
AudioPlayerObserverInterface::Context context;
|
|
|
|
context.audioItemId = AUDIO_ITEM_ID;
|
|
|
|
|
|
|
|
// Test onAudioPlayed() callback with 100ms offset
|
|
|
|
std::promise<void> wakePlayPromise;
|
|
|
|
std::future<void> wakePlayFuture = wakePlayPromise.get_future();
|
|
|
|
context.offset = std::chrono::milliseconds(100);
|
2018-03-09 00:55:39 +00:00
|
|
|
EXPECT_CALL(*m_mockGui, renderPlayerInfoCard(PLAYERINFO_PAYLOAD, _, _))
|
2017-10-30 22:14:38 +00:00
|
|
|
.Times(Exactly(1))
|
2018-03-09 00:55:39 +00:00
|
|
|
.WillOnce(Invoke([&wakePlayPromise, context](
|
|
|
|
const std::string& jsonPayload,
|
|
|
|
TemplateRuntimeObserverInterface::AudioPlayerInfo audioPlayerInfo,
|
|
|
|
avsCommon::avs::FocusState focusState) {
|
|
|
|
EXPECT_EQ(audioPlayerInfo.audioPlayerState, avsCommon::avs::PlayerActivity::PLAYING);
|
|
|
|
EXPECT_EQ(audioPlayerInfo.offset, context.offset);
|
|
|
|
wakePlayPromise.set_value();
|
|
|
|
}));
|
2017-10-30 22:14:38 +00:00
|
|
|
m_templateRuntime->onPlayerActivityChanged(avsCommon::avs::PlayerActivity::PLAYING, context);
|
|
|
|
wakePlayFuture.wait_for(TIMEOUT);
|
|
|
|
|
|
|
|
// Test onAudioPaused() callback with 200ms offset
|
|
|
|
std::promise<void> wakePausePromise;
|
|
|
|
std::future<void> wakePauseFuture = wakePausePromise.get_future();
|
|
|
|
context.offset = std::chrono::milliseconds(200);
|
2018-03-09 00:55:39 +00:00
|
|
|
EXPECT_CALL(*m_mockGui, renderPlayerInfoCard(PLAYERINFO_PAYLOAD, _, _))
|
2017-10-30 22:14:38 +00:00
|
|
|
.Times(Exactly(1))
|
2018-03-09 00:55:39 +00:00
|
|
|
.WillOnce(Invoke([&wakePausePromise, context](
|
|
|
|
const std::string& jsonPayload,
|
|
|
|
TemplateRuntimeObserverInterface::AudioPlayerInfo audioPlayerInfo,
|
|
|
|
avsCommon::avs::FocusState focusState) {
|
|
|
|
EXPECT_EQ(audioPlayerInfo.audioPlayerState, avsCommon::avs::PlayerActivity::PAUSED);
|
|
|
|
EXPECT_EQ(audioPlayerInfo.offset, context.offset);
|
|
|
|
wakePausePromise.set_value();
|
|
|
|
}));
|
2017-10-30 22:14:38 +00:00
|
|
|
m_templateRuntime->onPlayerActivityChanged(avsCommon::avs::PlayerActivity::PAUSED, context);
|
|
|
|
wakePauseFuture.wait_for(TIMEOUT);
|
|
|
|
|
|
|
|
// Test onAudioStopped() callback with 300ms offset
|
|
|
|
std::promise<void> wakeStopPromise;
|
|
|
|
std::future<void> wakeStopFuture = wakeStopPromise.get_future();
|
|
|
|
context.offset = std::chrono::milliseconds(300);
|
2018-03-09 00:55:39 +00:00
|
|
|
EXPECT_CALL(*m_mockGui, renderPlayerInfoCard(PLAYERINFO_PAYLOAD, _, _))
|
2017-10-30 22:14:38 +00:00
|
|
|
.Times(Exactly(1))
|
2018-03-09 00:55:39 +00:00
|
|
|
.WillOnce(Invoke([&wakeStopPromise, context](
|
|
|
|
const std::string& jsonPayload,
|
|
|
|
TemplateRuntimeObserverInterface::AudioPlayerInfo audioPlayerInfo,
|
|
|
|
avsCommon::avs::FocusState focusState) {
|
|
|
|
EXPECT_EQ(audioPlayerInfo.audioPlayerState, avsCommon::avs::PlayerActivity::STOPPED);
|
|
|
|
EXPECT_EQ(audioPlayerInfo.offset, context.offset);
|
|
|
|
wakeStopPromise.set_value();
|
|
|
|
}));
|
2017-10-30 22:14:38 +00:00
|
|
|
m_templateRuntime->onPlayerActivityChanged(avsCommon::avs::PlayerActivity::STOPPED, context);
|
|
|
|
wakeStopFuture.wait_for(TIMEOUT);
|
|
|
|
|
|
|
|
// Test onAudioFinished() callback with 400ms offset
|
|
|
|
std::promise<void> wakeFinishPromise;
|
|
|
|
std::future<void> wakeFinishFuture = wakeFinishPromise.get_future();
|
|
|
|
context.offset = std::chrono::milliseconds(400);
|
2018-03-09 00:55:39 +00:00
|
|
|
EXPECT_CALL(*m_mockGui, renderPlayerInfoCard(PLAYERINFO_PAYLOAD, _, _))
|
2017-10-30 22:14:38 +00:00
|
|
|
.Times(Exactly(1))
|
2018-03-09 00:55:39 +00:00
|
|
|
.WillOnce(Invoke([&wakeFinishPromise, context](
|
|
|
|
const std::string& jsonPayload,
|
|
|
|
TemplateRuntimeObserverInterface::AudioPlayerInfo audioPlayerInfo,
|
|
|
|
avsCommon::avs::FocusState focusState) {
|
|
|
|
EXPECT_EQ(audioPlayerInfo.audioPlayerState, avsCommon::avs::PlayerActivity::FINISHED);
|
|
|
|
EXPECT_EQ(audioPlayerInfo.offset, context.offset);
|
|
|
|
wakeFinishPromise.set_value();
|
|
|
|
}));
|
2017-10-30 22:14:38 +00:00
|
|
|
m_templateRuntime->onPlayerActivityChanged(avsCommon::avs::PlayerActivity::FINISHED, context);
|
|
|
|
wakeFinishFuture.wait_for(TIMEOUT);
|
|
|
|
}
|
|
|
|
|
2018-03-09 00:55:39 +00:00
|
|
|
/**
|
|
|
|
* Tests that if focus is changed to none, the clearTemplateCard() will be called.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(TemplateRuntimeTest, test_focusNone) {
|
2018-03-09 00:55:39 +00:00
|
|
|
// Create Directive.
|
|
|
|
auto attachmentManager = std::make_shared<StrictMock<MockAttachmentManager>>();
|
|
|
|
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(TEMPLATE.nameSpace, TEMPLATE.name, MESSAGE_ID);
|
|
|
|
std::shared_ptr<AVSDirective> directive =
|
|
|
|
AVSDirective::create("", avsMessageHeader, TEMPLATE_PAYLOAD, attachmentManager, "");
|
|
|
|
|
|
|
|
EXPECT_CALL(*m_mockGui, renderTemplateCard(TEMPLATE_PAYLOAD, _))
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnRenderTemplateCard));
|
|
|
|
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted())
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnSetCompleted));
|
|
|
|
EXPECT_CALL(*m_mockGui, clearTemplateCard())
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnClearTemplateCard));
|
|
|
|
|
|
|
|
m_templateRuntime->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
|
|
|
|
m_templateRuntime->CapabilityAgent::handleDirective(MESSAGE_ID);
|
|
|
|
m_wakeSetCompletedFuture.wait_for(TIMEOUT);
|
|
|
|
m_wakeRenderTemplateCardFuture.wait_for(TIMEOUT);
|
|
|
|
m_templateRuntime->onFocusChanged(FocusState::NONE);
|
|
|
|
m_wakeClearTemplateCardFuture.wait_for(TIMEOUT);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests that if displayCardCleared() is called, the clearTemplateCard() will not be called.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(TemplateRuntimeTest, test_displayCardCleared) {
|
2018-03-09 00:55:39 +00:00
|
|
|
// Create Directive.
|
|
|
|
auto attachmentManager = std::make_shared<StrictMock<MockAttachmentManager>>();
|
|
|
|
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(TEMPLATE.nameSpace, TEMPLATE.name, MESSAGE_ID);
|
|
|
|
std::shared_ptr<AVSDirective> directive =
|
|
|
|
AVSDirective::create("", avsMessageHeader, TEMPLATE_PAYLOAD, attachmentManager, "");
|
|
|
|
|
|
|
|
EXPECT_CALL(*m_mockGui, renderTemplateCard(TEMPLATE_PAYLOAD, _))
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnRenderTemplateCard));
|
|
|
|
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted())
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnSetCompleted));
|
|
|
|
EXPECT_CALL(*m_mockGui, clearTemplateCard()).Times(Exactly(0));
|
|
|
|
EXPECT_CALL(*m_mockFocusManager, releaseChannel(_, _)).Times(Exactly(1)).WillOnce(InvokeWithoutArgs([this] {
|
|
|
|
auto releaseChannelSuccess = std::make_shared<std::promise<bool>>();
|
|
|
|
std::future<bool> returnValue = releaseChannelSuccess->get_future();
|
|
|
|
m_templateRuntime->onFocusChanged(avsCommon::avs::FocusState::NONE);
|
|
|
|
releaseChannelSuccess->set_value(true);
|
|
|
|
wakeOnReleaseChannel();
|
|
|
|
return returnValue;
|
|
|
|
}));
|
|
|
|
|
|
|
|
m_templateRuntime->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
|
|
|
|
m_templateRuntime->CapabilityAgent::handleDirective(MESSAGE_ID);
|
|
|
|
m_wakeSetCompletedFuture.wait_for(TIMEOUT);
|
|
|
|
m_wakeRenderTemplateCardFuture.wait_for(TIMEOUT);
|
|
|
|
m_templateRuntime->displayCardCleared();
|
|
|
|
m_wakeReleaseChannelFuture.wait_for(TIMEOUT);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Tests that if another displayCard event is sent before channel's focus is set to none, the state machine would
|
|
|
|
* transition to REACQUIRING state and acquireChannel again to display the card.
|
|
|
|
*/
|
2019-05-22 23:06:18 +00:00
|
|
|
TEST_F(TemplateRuntimeTest, test_reacquireChannel) {
|
2018-03-09 00:55:39 +00:00
|
|
|
// Create RenderPlayerInfo Directive and wait until PlayerInfo card is displayed.
|
|
|
|
auto attachmentManager = std::make_shared<StrictMock<MockAttachmentManager>>();
|
|
|
|
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(PLAYER_INFO.nameSpace, PLAYER_INFO.name, MESSAGE_ID);
|
|
|
|
std::shared_ptr<AVSDirective> directive =
|
|
|
|
AVSDirective::create("", avsMessageHeader, PLAYERINFO_PAYLOAD, attachmentManager, "");
|
|
|
|
|
|
|
|
EXPECT_CALL(*m_mockGui, renderPlayerInfoCard(PLAYERINFO_PAYLOAD, _, _))
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnRenderPlayerInfoCard));
|
|
|
|
|
|
|
|
AudioPlayerObserverInterface::Context context;
|
|
|
|
context.audioItemId = AUDIO_ITEM_ID;
|
|
|
|
context.offset = TIMEOUT;
|
|
|
|
m_templateRuntime->onPlayerActivityChanged(avsCommon::avs::PlayerActivity::PLAYING, context);
|
|
|
|
m_templateRuntime->handleDirectiveImmediately(directive);
|
|
|
|
m_wakeRenderPlayerInfoCardFuture.wait_for(TIMEOUT);
|
|
|
|
|
|
|
|
// Send displayCardCleared() to clear card, before setting focus to NONE, send another TemplateCard.
|
|
|
|
EXPECT_CALL(*m_mockFocusManager, releaseChannel(_, _)).Times(Exactly(1)).WillOnce(InvokeWithoutArgs([this] {
|
|
|
|
auto releaseChannelSuccess = std::make_shared<std::promise<bool>>();
|
|
|
|
std::future<bool> returnValue = releaseChannelSuccess->get_future();
|
|
|
|
releaseChannelSuccess->set_value(true);
|
|
|
|
wakeOnReleaseChannel();
|
|
|
|
return returnValue;
|
|
|
|
}));
|
|
|
|
m_templateRuntime->displayCardCleared();
|
|
|
|
m_wakeReleaseChannelFuture.wait_for(TIMEOUT);
|
|
|
|
|
|
|
|
// Create RenderTemplate Directive and see if channel is reacquire correctly.
|
|
|
|
auto avsMessageHeader1 = std::make_shared<AVSMessageHeader>(TEMPLATE.nameSpace, TEMPLATE.name, MESSAGE_ID);
|
|
|
|
std::shared_ptr<AVSDirective> directive1 =
|
|
|
|
AVSDirective::create("", avsMessageHeader1, TEMPLATE_PAYLOAD, attachmentManager, "");
|
|
|
|
|
|
|
|
EXPECT_CALL(*m_mockGui, renderTemplateCard(TEMPLATE_PAYLOAD, _))
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnRenderTemplateCard));
|
|
|
|
|
|
|
|
m_templateRuntime->handleDirectiveImmediately(directive1);
|
|
|
|
m_templateRuntime->onFocusChanged(avsCommon::avs::FocusState::NONE);
|
|
|
|
m_wakeRenderTemplateCardFuture.wait_for(TIMEOUT);
|
|
|
|
}
|
|
|
|
|
2019-05-22 23:06:18 +00:00
|
|
|
/**
|
|
|
|
* Test that we should skip rendering a player info card if the audio has already changed.
|
|
|
|
*/
|
|
|
|
TEST_F(TemplateRuntimeTest, testRenderPlayerInfoAfterPlayerActivityChanged) {
|
|
|
|
// Create Directive.
|
|
|
|
auto attachmentManager = std::make_shared<StrictMock<MockAttachmentManager>>();
|
|
|
|
auto avsMessageHeader = std::make_shared<AVSMessageHeader>(PLAYER_INFO.nameSpace, PLAYER_INFO.name, MESSAGE_ID);
|
|
|
|
std::shared_ptr<AVSDirective> directive =
|
|
|
|
AVSDirective::create("", avsMessageHeader, PLAYERINFO_PAYLOAD, attachmentManager, "");
|
|
|
|
|
|
|
|
AudioPlayerObserverInterface::Context context;
|
|
|
|
context.audioItemId = AUDIO_ITEM_ID;
|
|
|
|
m_templateRuntime->onPlayerActivityChanged(avsCommon::avs::PlayerActivity::PLAYING, context);
|
|
|
|
|
|
|
|
::testing::InSequence s;
|
|
|
|
EXPECT_CALL(*m_mockFocusManager, acquireChannel(_, _, _)).WillOnce(Return(true));
|
|
|
|
// Send a directive first to TemplateRuntime
|
|
|
|
EXPECT_CALL(*m_mockDirectiveHandlerResult, setCompleted())
|
|
|
|
.Times(Exactly(1))
|
|
|
|
.WillOnce(InvokeWithoutArgs(this, &TemplateRuntimeTest::wakeOnSetCompleted));
|
|
|
|
m_templateRuntime->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
|
|
|
|
m_templateRuntime->CapabilityAgent::handleDirective(MESSAGE_ID);
|
|
|
|
m_wakeSetCompletedFuture.wait_for(TIMEOUT);
|
|
|
|
|
|
|
|
// Test onAudioPlayed() callback with 100ms offset
|
|
|
|
std::promise<void> wakePlayPromise;
|
|
|
|
std::future<void> wakePlayFuture = wakePlayPromise.get_future();
|
|
|
|
context.offset = std::chrono::milliseconds(100);
|
|
|
|
EXPECT_CALL(*m_mockGui, renderPlayerInfoCard(PLAYERINFO_PAYLOAD, _, _)).Times(0);
|
|
|
|
EXPECT_CALL(*m_mockFocusManager, releaseChannel(_, _)).Times(Exactly(1)).WillOnce(InvokeWithoutArgs([this] {
|
|
|
|
auto releaseChannelSuccess = std::make_shared<std::promise<bool>>();
|
|
|
|
std::future<bool> returnValue = releaseChannelSuccess->get_future();
|
|
|
|
m_templateRuntime->onFocusChanged(avsCommon::avs::FocusState::NONE);
|
|
|
|
releaseChannelSuccess->set_value(true);
|
|
|
|
wakeOnReleaseChannel();
|
|
|
|
return returnValue;
|
|
|
|
}));
|
|
|
|
|
|
|
|
m_templateRuntime->CapabilityAgent::preHandleDirective(directive, std::move(m_mockDirectiveHandlerResult));
|
|
|
|
m_templateRuntime->CapabilityAgent::handleDirective(MESSAGE_ID);
|
|
|
|
m_wakeSetCompletedFuture.wait_for(TIMEOUT);
|
|
|
|
m_wakeRenderTemplateCardFuture.wait_for(TIMEOUT);
|
|
|
|
m_templateRuntime->displayCardCleared();
|
|
|
|
m_wakeReleaseChannelFuture.wait_for(TIMEOUT);
|
|
|
|
context.audioItemId = AUDIO_ITEM_ID_1;
|
|
|
|
m_templateRuntime->onPlayerActivityChanged(avsCommon::avs::PlayerActivity::PLAYING, context);
|
|
|
|
m_templateRuntime->onFocusChanged(avsCommon::avs::FocusState::FOREGROUND);
|
|
|
|
m_templateRuntime->displayCardCleared();
|
|
|
|
m_wakeReleaseChannelFuture.wait_for(TIMEOUT);
|
|
|
|
}
|
|
|
|
|
2017-10-30 22:14:38 +00:00
|
|
|
} // namespace test
|
|
|
|
} // namespace templateRuntime
|
|
|
|
} // namespace capabilityAgents
|
|
|
|
} // namespace alexaClientSDK
|