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;
}
}