35
35
struct media::ServiceImplementation::Private
37
typedef map<media::Player::PlayerKey, std::shared_ptr<media::Player>> player_map_t;
41
resume_key(UINT32_MAX)
38
: resume_key(std::numeric_limits<std::uint32_t>::max())
43
40
bus = std::shared_ptr<dbus::Bus>(new dbus::Bus(core::dbus::WellKnownBus::session));
44
41
bus->install_executor(dbus::asio::make_executor(bus));
52
49
auto stub_service = dbus::Service::use_service(bus, "com.canonical.indicator.power");
53
50
indicator_power_session = stub_service->object_for_path(dbus::types::ObjectPath("/com/canonical/indicator/power/Battery"));
54
51
power_level = indicator_power_session->get_property<core::IndicatorPower::PowerLevel>();
55
power_level->changed().connect([this](const core::IndicatorPower::PowerLevel::ValueType &level)
57
// When the battery level hits 10% or 5%, pause all multimedia sessions.
58
// Playback will resume when the user clears the presented notification.
59
if (level == "low" || level == "very_low")
60
pause_all_multimedia_sessions();
63
52
is_warning = indicator_power_session->get_property<core::IndicatorPower::IsWarning>();
64
is_warning->changed().connect([this](const core::IndicatorPower::IsWarning::ValueType ¬ifying)
66
// If the low battery level notification is no longer being displayed,
67
// resume what the user was previously playing
69
resume_multimedia_session();
81
void track_player(const std::shared_ptr<media::Player>& player)
84
std::pair<media::Player::PlayerKey,
85
std::shared_ptr<media::Player>>(key_, player));
90
inline media::Player::PlayerKey key() const
95
void pause_other_sessions(media::Player::PlayerKey key)
97
auto player_it = player_map.find(key);
98
if (player_it != player_map.end())
100
auto ¤t_player = (*player_it).second;
101
for (auto& player_pair : player_map)
103
// Only pause a Player if all of the following criteria are met:
104
// 1) currently playing
105
// 2) not the same player as the one passed in my key
106
// 3) new Player has an audio stream role set to multimedia
107
// 4) has an audio stream role set to multimedia
108
if (player_pair.second->playback_status() == Player::playing
109
&& player_pair.first != key
110
&& current_player->audio_stream_role() == media::Player::multimedia
111
&& player_pair.second->audio_stream_role() == media::Player::multimedia)
113
cout << "Pausing Player with key: " << player_pair.first << endl;
114
player_pair.second->pause();
119
cerr << "Could not find Player by key: " << key << endl;
122
// Pauses all multimedia audio stream role type Players
123
void pause_all_multimedia_sessions()
125
for (auto& player_pair : player_map)
127
if (player_pair.second->playback_status() == Player::playing
128
&& player_pair.second->audio_stream_role() == media::Player::multimedia)
130
resume_key = player_pair.first;
131
cout << "Will resume playback of Player with key: " << resume_key << endl;
132
player_pair.second->pause();
137
void resume_multimedia_session()
139
auto player_it = player_map.find(resume_key);
140
if (player_it != player_map.end())
142
auto &player = (*player_it).second;
143
if (player->playback_status() == Player::paused)
145
cout << "Resuming playback of Player with key: " << resume_key << endl;
147
resume_key = UINT32_MAX;
152
// Used for Player instance management
153
player_map_t player_map;
154
media::Player::PlayerKey key_;
155
63
// This holds the key of the multimedia role Player instance that was paused
156
64
// when the battery level reached 10% or 5%
157
65
media::Player::PlayerKey resume_key;
160
68
std::shared_ptr<dbus::Object> indicator_power_session;
161
69
std::shared_ptr<core::dbus::Property<core::IndicatorPower::PowerLevel>> power_level;
162
70
std::shared_ptr<core::dbus::Property<core::IndicatorPower::IsWarning>> is_warning;
166
73
media::ServiceImplementation::ServiceImplementation() : d(new Private())
168
75
cout << __PRETTY_FUNCTION__ << endl;
77
d->power_level->changed().connect([this](const core::IndicatorPower::PowerLevel::ValueType &level)
79
// When the battery level hits 10% or 5%, pause all multimedia sessions.
80
// Playback will resume when the user clears the presented notification.
81
if (level == "low" || level == "very_low")
82
pause_all_multimedia_sessions();
85
d->is_warning->changed().connect([this](const core::IndicatorPower::IsWarning::ValueType ¬ifying)
87
// If the low battery level notification is no longer being displayed,
88
// resume what the user was previously playing
90
resume_multimedia_session();
171
94
media::ServiceImplementation::~ServiceImplementation()
175
98
std::shared_ptr<media::Player> media::ServiceImplementation::create_session(
176
99
const media::Player::Configuration& conf)
178
std::shared_ptr<media::Player> player = std::make_shared<media::PlayerImplementation>(
179
conf.object_path, shared_from_this(), d->key());
180
d->track_player(player);
101
auto player = std::make_shared<media::PlayerImplementation>(
102
conf.identity, conf.bus, conf.session, shared_from_this(), conf.key);
105
player->on_client_disconnected().connect([this, key]()
107
remove_player_for_key(key);
184
113
void media::ServiceImplementation::pause_other_sessions(media::Player::PlayerKey key)
186
d->pause_other_sessions(key);
115
if (not has_player_for_key(key))
117
cerr << "Could not find Player by key: " << key << endl;
121
auto current_player = player_for_key(key);
123
// We immediately make the player known as new current player.
124
if (current_player->audio_stream_role() == media::Player::multimedia)
125
set_current_player_for_key(key);
127
enumerate_players([current_player, key](const media::Player::PlayerKey& other_key, const std::shared_ptr<media::Player>& other_player)
129
// Only pause a Player if all of the following criteria are met:
130
// 1) currently playing
131
// 2) not the same player as the one passed in my key
132
// 3) new Player has an audio stream role set to multimedia
133
// 4) has an audio stream role set to multimedia
134
if (other_player->playback_status() == Player::playing &&
136
current_player->audio_stream_role() == media::Player::multimedia &&
137
other_player->audio_stream_role() == media::Player::multimedia)
139
cout << "Pausing Player with key: " << other_key << endl;
140
other_player->pause();
145
void media::ServiceImplementation::pause_all_multimedia_sessions()
147
enumerate_players([this](const media::Player::PlayerKey& key, const std::shared_ptr<media::Player>& player)
149
if (player->playback_status() == Player::playing
150
&& player->audio_stream_role() == media::Player::multimedia)
153
cout << "Will resume playback of Player with key: " << d->resume_key << endl;
159
void media::ServiceImplementation::resume_multimedia_session()
161
if (not has_player_for_key(d->resume_key))
164
auto player = player_for_key(d->resume_key);
166
if (player->playback_status() == Player::paused)
168
cout << "Resuming playback of Player with key: " << d->resume_key << endl;
170
d->resume_key = std::numeric_limits<std::uint32_t>::max();