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事件
- AlertStarted Event
- AlertStopped Event
- AlertEnteredForeground Event <===FOCUS_ENTERED_FOREGROUND
- AlertEnteredBackground Event <===FOCUS_ENTERED_BACKGROUND
通過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;
}
}