Alexa SDK庖丁解牛-第六回:alerts模塊分析

1.涉及到的所有指令:

setting a timer, setting an alarm, setting a reminder or canceling a timer, alarm or reminder

2.Alerts必須保證網絡聯通,client需要接收server端的指令,所有的alerts指令都是雲端下發來完成設置的,不支持離線設置,設置成功後上報事件狀態;但是設備在網絡異常狀態下必須有必須有能力處理以前的定時任務;如果設備重啓,當前鬧鈴時刻在30分鐘時效內則執行鬧鈴;如果鬧鈴響起,長達一小時沒有關閉會自動關閉;

3.建議使用NTP時間,雲端根據時區和發送請求指令的時間來計算準確的UTC時間;

4.核心代碼邏輯:

m_alertScheduler.scheduleAlert

-》

void AlertScheduler::setTimerForNextAlertLocked()

-》

m_scheduledAlertTimer

.start.()..valid()

1)start會創建timer,並綁定狀態更新函數;

2)AlertScheduler::onAlertReady(const std::string& alertToken)

=》

AlertScheduler::notifyObserver()

=》

AlertScheduler::executeNotifyObserver()

=》

AlertsCapabilityAgent::onAlertStateChange()

=》

AlertsCapabilityAgent::executeOnAlertStateChange()

{

//此處會把任務交給一個線程來處理,併發應用

case AlertObserverInterface::State::READY:

acquireChannel();

//任務提交給線程

executeNotifyObservers()

}

AlertScheduler::m_observer原型:

AlertsCapabilityAgent::initializeAlerts()

{

m_alertScheduler.initialize(storageFilePath, shared_from_this());

=》

AlertScheduler::m_observer = AlertsCapabilityAgent;

}

=》

AlertsCapabilityAgent::acquireChannel()

=》

FocusManager::acquireChannel()

=》

FocusManager::acquireChannelHelper()

{

channelToAcquire->setObserver(channelObserver);

channelToAcquire->setFocus(FocusState::FOREGROUND);

}

=》

Channel::setFocus()

=》

AlertsCapabilityAgent::onFocusChanged()

=》

AlertsCapabilityAgent::executeOnFocusChanged()

=》

AlertScheduler::updateFocus()

=》

AlertScheduler::activateNextAlertLocked()

=》

Alert::activate()

=》

Alert::startRenderer()

{

rendererCopy->setObserver(shared_from_this());

rendererCopy->start(audioFactory, urls, loopCount, loopPause);

}

Renderer::start()

=》

Renderer::executeStart()

1) m_mediaPlayer->setSource

2) m_mediaPlayer->play

 

1)MediaPlayer::setSource();

//傳遞了audioFactory()作爲參數

MediaPlayer::SourceId MediaPlayer::setSource(std::shared_ptr<std::istream> stream, bool repeat)

{

handleSetIStreamSource(stream, repeat, &promise);

}

void MediaPlayer::handleSetIStreamSource(

std::shared_ptr<std::istream> stream,

bool repeat,

std::promise<MediaPlayer::SourceId>* promise) {

std::shared_ptr<SourceInterface> source = IStreamSource::create(this, stream, repeat);

if (!g_signal_connect(m_pipeline.decoder, "pad-added", G_CALLBACK(onPadAdded), this)) {

ACSDK_ERROR(LX("handleSetIStreamSourceFailed").d("reason", "connectPadAddedSignalFailed"));

promise->set_value(ERROR_SOURCE_ID);

return;

}

m_source = source;

}

std::unique_ptr<IStreamSource> IStreamSource::create(

PipelineInterface* pipeline,

std::shared_ptr<std::istream> stream,

bool repeat) {

std::unique_ptr<IStreamSource> result(new IStreamSource(pipeline, std::move(stream), repeat));

if (result->init()) {

return result;

}

return nullptr;

};

由於IStreamSource繼承的BaseStreamSource,使用基類的init成員函數bool BaseStreamSource::init() {

}

其中註冊了很多回調函數,appsrc,decoder,onNeedData,onEnoughData,onSeekData

2)MediaPlayer::play();

buffer的狀態更新會觸發回調函數:

m_busWatchId = gst_bus_add_watch(bus, &MediaPlayer::onBusMessage, this);

MediaPlayer::onBusMessage()

{

return static_cast<MediaPlayer*>(mediaPlayer)->handleBusMessage(message);

}

 

MediaPlayer::handleBusMessage(GstMessage* message) {

}

 

void MediaPlayer::sendPlaybackStarted() {

m_playerObserver->onPlaybackStarted(m_currentId);

}

void Renderer::onPlaybackStarted(SourceId sourceId) {

m_executor.submit([this, sourceId]() { executeOnPlaybackStarted(sourceId); });

}

void Renderer::executeOnPlaybackStarted(SourceId sourceId) {

notifyObserver(RendererObserverInterface::State::STARTED);

}

void Renderer::notifyObserver(RendererObserverInterface::State state, const std::string& message) {

if (m_observer) {

m_observer->onRendererStateChange(state, message);

}

}

void Alert::onRendererStateChange(

}

alert狀態更新,並反饋給AVS server

 

備註:

1.alert使用的本地音頻數據,數組形式存儲;

2.MediaPlayer::SourceId MediaPlayer::setSource有三種形式,alert以setSource(std::shared_ptr<std::istream> stream, bool repeat)形式存在;

另外兩種爲:

1)setSource(std::shared_ptr<avsCommon::avs::attachment::AttachmentReader> reader)

2)setSource(const std::string& url, std::chrono::milliseconds offset)其實是1)的變種形式

 

event反饋: SetAlertSucceeded Event, SetAlertFailed Event,DeleteAlertSucceeded Event, DeleteAlertFailed Event通過messageSender把event消息送入http2處理隊列;其他的event事件

通過MediaPlayer的狀態變化來觸發:

MediaPlayer::sendPlaybackStarted》

Renderer::onPlaybackStarted=》

Renderer::executeOnPlaybackStarted=》

Alert::onRendererStateChange =》AlertsCapabilityAgent::onAlertStateChange=》 AlertsCapabilityAgent::executeOnAlertStateChange

 

1)void AlertScheduler::executeOnAlertStateChange與void AlertsCapabilityAgent::executeOnAlertStateChange區別,AlertScheduler與AlertsCapabilityAgent關係

2)AlertScheduler::updateFocus通知

AlertScheduler::notifyObserver()

AlertScheduler::executeNotifyObserver()

AlertsCapabilityAgent::onAlertStateChange()

AlertsCapabilityAgent::executeOnAlertStateChange()

 

void AlertScheduler::updateFocus(avsCommon::avs::FocusState focusState)

{

switch (m_focusState) {

case FocusState::FOREGROUND:

if (m_activeAlert) {

m_activeAlert->setFocusState(m_focusState);

auto token = m_activeAlert->getToken();

notifyObserver(token, AlertObserverInterface::State::FOCUS_ENTERED_FOREGROUND);

} else {

activateNextAlertLocked();

}

return;

 

case FocusState::BACKGROUND:

if (m_activeAlert) {

m_activeAlert->setFocusState(m_focusState);

auto token = m_activeAlert->getToken();

notifyObserver(token, AlertObserverInterface::State::FOCUS_ENTERED_BACKGROUND);

} else {

activateNextAlertLocked();

}

return;

 

case FocusState::NONE:

deactivateActiveAlertHelperLocked(Alert::StopReason::LOCAL_STOP);

return;

}

}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章