46 #include <pulse/pulseaudio.h>
50 using namespace media;
53 namespace MediaHubService {
64 void pause_all_multimedia_sessions(
bool resume_play_after_phonecall);
65 void resume_paused_multimedia_sessions(
bool resume_video_sessions =
true);
66 void resume_multimedia_session();
76 media::power::BatteryObserver battery_observer;
77 media::power::StateController::Ptr power_state_controller;
80 media::audio::OutputObserver audio_output_observer;
83 media::telephony::CallMonitor call_monitor;
86 std::list<std::pair<media::Player::PlayerKey, bool>> paused_sessions;
88 QHash<Player::PlayerKey, PlayerImplementation *> m_players;
96 resume_key(
Player::invalidKey),
97 power_state_controller(
media::power::StateController::instance()),
100 m_currentPlayer(
Player::invalidKey),
103 QObject::connect(&battery_observer,
107 const bool resume_play_after_phonecall =
false;
110 switch (battery_observer.level())
112 case media::power::Level::low:
113 case media::power::Level::very_low:
116 pause_all_multimedia_sessions(resume_play_after_phonecall);
123 QObject::connect(&battery_observer,
129 if (!battery_observer.isWarningActive())
133 QObject::connect(&audio_output_observer,
138 const bool resume_play_after_phonecall =
false;
142 MH_INFO(
"AudioOutputObserver reports that output is now Headphones/Headset.");
145 MH_INFO(
"AudioOutputObserver reports that output is now Speaker.");
151 MH_INFO(
"AudioOutputObserver reports that output is now External.");
154 audio_output_state = state;
157 QObject::connect(&call_monitor,
161 const bool resume_play_after_phonecall =
true;
162 switch (call_monitor.callState()) {
163 case media::telephony::CallMonitor::State::OffHook:
164 MH_INFO(
"Got call started signal, pausing all multimedia sessions");
167 pause_all_multimedia_sessions(resume_play_after_phonecall);
169 case media::telephony::CallMonitor::State::OnHook:
170 MH_INFO(
"Got call ended signal, resuming paused multimedia sessions");
171 resume_paused_multimedia_sessions(false);
176 QObject::connect(&recorder_observer,
181 if (state == media::RecordingState::started)
183 power_state_controller->requestDisplayOn();
186 const bool resume_play_after_phonecall =
false;
191 power_state_controller->releaseDisplayOn();
198 for (
auto i = m_players.begin(); i != m_players.end(); i++) {
205 auto paused_player_pair = std::make_pair(key, resume_play_after_phonecall);
206 paused_sessions.push_back(paused_player_pair);
207 MH_INFO(
"Pausing Player with key: %d, resuming after phone call? %s", key,
208 (resume_play_after_phonecall ?
"yes" :
"no"));
216 std::for_each(paused_sessions.begin(), paused_sessions.end(),
217 [
this, resume_video_sessions](
const std::pair<media::Player::PlayerKey, bool> &paused_player_pair) {
218 const media::Player::PlayerKey key = paused_player_pair.first;
219 const bool resume_play_after_phonecall = paused_player_pair.second;
220 PlayerImplementation *player = m_players.value(key);
222 MH_WARNING(
"Failed to look up Player instance for key %d"
223 ", no valid Player instance for that key value and cannot automatically resume"
224 " paused players. This most likely means that media-hub-server has crashed and"
229 if ((resume_video_sessions || player->isAudioSource()) && resume_play_after_phonecall)
232 MH_INFO(
"Not auto-resuming video player session or other type of player session.");
235 paused_sessions.clear();
238 void ServiceImplementationPrivate::resume_multimedia_session()
242 MH_WARNING(
"Failed to look up Player instance for key %d"
243 ", no valid Player instance for that key value and cannot automatically resume"
244 " paused Player. This most likely means that media-hub-server has crashed and"
245 " restarted.", resume_key);
249 if (player->playbackStatus() == Player::paused)
251 MH_INFO(
"Resuming playback of Player with key: %d", resume_key);
253 resume_key = Player::invalidKey;
260 if (key == m_currentPlayer)
return;
261 m_currentPlayer = key;
262 Q_EMIT q->currentPlayerChanged();
270 if (not current_player)
272 MH_WARNING(
"Could not find Player by key: %d", key);
276 for (
auto i = m_players.begin(); i != m_players.end(); i++) {
286 other_player->
client().
name != current_player->client().name &&
290 MH_INFO(
"Pausing Player with key: %d", other_key);
291 other_player->
pause();
299 MH_DEBUG(
"==== Pausing all other multimedia player sessions");
300 if (not pause_other_sessions(key)) {
301 MH_WARNING(
"Failed to pause other player sessions");
304 MH_DEBUG(
"==== Updating the current player");
305 setCurrentPlayer(key);
308 ServiceImplementation::ServiceImplementation(
QObject *parent):
326 d->client_death_observer,
330 this, [
this, key=client.
key]()
332 Q_D(ServiceImplementation);
334 PlayerImplementation *player = d->m_players.value(key);
336 player->audioStreamRole() == Player::AudioStreamRole::multimedia &&
337 key == currentPlayer())
339 MH_DEBUG(
"==== Resetting current player");
340 d->setCurrentPlayer(Player::invalidKey);
343 if (player->lifetime() == Player::Lifetime::normal) {
344 d->m_players.remove(key);
345 player->deleteLater();
350 this, [d, key=client.key]() {
351 d->onPlaybackRequested(key);
354 d->m_players[client.key] = player;
361 return d->m_players.value(key);
368 d->pause_other_sessions(key);
374 return d->m_currentPlayer;