~ubuntu-branches/ubuntu/vivid/media-hub/vivid-updates

« back to all changes in this revision

Viewing changes to src/core/media/service_implementation.cpp

  • Committer: Package Import Robot
  • Author(s): Ubuntu daily release, Thomas Voß, Ubuntu daily release, thomas-voss
  • Date: 2014-09-10 21:11:02 UTC
  • mfrom: (1.1.15)
  • Revision ID: package-import@ubuntu.com-20140910211102-x6bhfqah5c4mqs2d
Tags: 2.0.0+14.10.20140910.2-0ubuntu1
[ Thomas Voß ]
* Bump major version to account for signature changes in public interface. 

[ Ubuntu daily release ]
* debian/libmedia-hub-common2.symbols: auto-update to released version

[ thomas-voss ]
* Get rid of custom macros and use the ones provided by dbus-cpp.
  Adjust to changes due to making org.mpris.MediaPlayer2.Player
  compliant to the spec.

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include "player_configuration.h"
24
24
#include "player_implementation.h"
25
25
 
 
26
#include <cstdint>
26
27
#include <map>
27
28
#include <memory>
28
 
#include <stdint.h>
29
29
#include <thread>
30
30
 
31
31
namespace media = core::ubuntu::media;
34
34
 
35
35
struct media::ServiceImplementation::Private
36
36
{
37
 
    typedef map<media::Player::PlayerKey, std::shared_ptr<media::Player>> player_map_t;
38
 
 
39
37
    Private()
40
 
        : key_(0),
41
 
          resume_key(UINT32_MAX)
 
38
        : resume_key(std::numeric_limits<std::uint32_t>::max())
42
39
    {
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)
56
 
        {
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();
61
 
        });
62
 
 
63
52
        is_warning = indicator_power_session->get_property<core::IndicatorPower::IsWarning>();
64
 
        is_warning->changed().connect([this](const core::IndicatorPower::IsWarning::ValueType &notifying)
65
 
        {
66
 
            // If the low battery level notification is no longer being displayed,
67
 
            // resume what the user was previously playing
68
 
            if (!notifying)
69
 
                resume_multimedia_session();
70
 
        });
71
53
    }
72
54
 
73
55
    ~Private()
78
60
            worker.join();
79
61
    }
80
62
 
81
 
    void track_player(const std::shared_ptr<media::Player>& player)
82
 
    {
83
 
        player_map.insert(
84
 
                std::pair<media::Player::PlayerKey,
85
 
                std::shared_ptr<media::Player>>(key_, player));
86
 
 
87
 
        ++key_;
88
 
    }
89
 
 
90
 
    inline media::Player::PlayerKey key() const
91
 
    {
92
 
        return key_;
93
 
    }
94
 
 
95
 
    void pause_other_sessions(media::Player::PlayerKey key)
96
 
    {
97
 
        auto player_it = player_map.find(key);
98
 
        if (player_it != player_map.end())
99
 
        {
100
 
            auto &current_player = (*player_it).second;
101
 
            for (auto& player_pair : player_map)
102
 
            {
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)
112
 
                {
113
 
                    cout << "Pausing Player with key: " << player_pair.first << endl;
114
 
                    player_pair.second->pause();
115
 
                }
116
 
            }
117
 
        }
118
 
        else
119
 
            cerr << "Could not find Player by key: " << key << endl;
120
 
    }
121
 
 
122
 
    // Pauses all multimedia audio stream role type Players
123
 
    void pause_all_multimedia_sessions()
124
 
    {
125
 
        for (auto& player_pair : player_map)
126
 
        {
127
 
            if (player_pair.second->playback_status() == Player::playing
128
 
                    && player_pair.second->audio_stream_role() == media::Player::multimedia)
129
 
            {
130
 
                resume_key = player_pair.first;
131
 
                cout << "Will resume playback of Player with key: " << resume_key << endl;
132
 
                player_pair.second->pause();
133
 
            }
134
 
        }
135
 
    }
136
 
 
137
 
    void resume_multimedia_session()
138
 
    {
139
 
        auto player_it = player_map.find(resume_key);
140
 
        if (player_it != player_map.end())
141
 
        {
142
 
            auto &player = (*player_it).second;
143
 
            if (player->playback_status() == Player::paused)
144
 
            {
145
 
                cout << "Resuming playback of Player with key: " << resume_key << endl;
146
 
                player->play();
147
 
                resume_key = UINT32_MAX;
148
 
            }
149
 
        }
150
 
    }
151
 
 
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;
163
 
 
164
71
};
165
72
 
166
73
media::ServiceImplementation::ServiceImplementation() : d(new Private())
167
74
{
168
75
    cout << __PRETTY_FUNCTION__ << endl;
 
76
 
 
77
    d->power_level->changed().connect([this](const core::IndicatorPower::PowerLevel::ValueType &level)
 
78
    {
 
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();
 
83
    });
 
84
 
 
85
    d->is_warning->changed().connect([this](const core::IndicatorPower::IsWarning::ValueType &notifying)
 
86
    {
 
87
        // If the low battery level notification is no longer being displayed,
 
88
        // resume what the user was previously playing
 
89
        if (!notifying)
 
90
            resume_multimedia_session();
 
91
    });
169
92
}
170
93
 
171
94
media::ServiceImplementation::~ServiceImplementation()
175
98
std::shared_ptr<media::Player> media::ServiceImplementation::create_session(
176
99
        const media::Player::Configuration& conf)
177
100
{
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);
 
103
 
 
104
    auto key = conf.key;
 
105
    player->on_client_disconnected().connect([this, key]()
 
106
    {
 
107
        remove_player_for_key(key);
 
108
    });
 
109
 
181
110
    return player;
182
111
}
183
112
 
184
113
void media::ServiceImplementation::pause_other_sessions(media::Player::PlayerKey key)
185
114
{
186
 
    d->pause_other_sessions(key);
 
115
    if (not has_player_for_key(key))
 
116
    {
 
117
        cerr << "Could not find Player by key: " << key << endl;
 
118
        return;
 
119
    }
 
120
 
 
121
    auto current_player = player_for_key(key);
 
122
 
 
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);
 
126
 
 
127
    enumerate_players([current_player, key](const media::Player::PlayerKey& other_key, const std::shared_ptr<media::Player>& other_player)
 
128
    {
 
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 &&
 
135
            other_key != key &&
 
136
            current_player->audio_stream_role() == media::Player::multimedia &&
 
137
            other_player->audio_stream_role() == media::Player::multimedia)
 
138
        {
 
139
            cout << "Pausing Player with key: " << other_key << endl;
 
140
            other_player->pause();
 
141
        }
 
142
    });
 
143
}
 
144
 
 
145
void media::ServiceImplementation::pause_all_multimedia_sessions()
 
146
{
 
147
    enumerate_players([this](const media::Player::PlayerKey& key, const std::shared_ptr<media::Player>& player)
 
148
                      {
 
149
                          if (player->playback_status() == Player::playing
 
150
                              && player->audio_stream_role() == media::Player::multimedia)
 
151
                          {
 
152
                              d->resume_key = key;
 
153
                              cout << "Will resume playback of Player with key: " << d->resume_key << endl;
 
154
                              player->pause();
 
155
                          }
 
156
                      });
 
157
}
 
158
 
 
159
void media::ServiceImplementation::resume_multimedia_session()
 
160
{
 
161
    if (not has_player_for_key(d->resume_key))
 
162
        return;
 
163
 
 
164
    auto player = player_for_key(d->resume_key);
 
165
 
 
166
    if (player->playback_status() == Player::paused)
 
167
    {
 
168
        cout << "Resuming playback of Player with key: " << d->resume_key << endl;
 
169
        player->play();
 
170
        d->resume_key = std::numeric_limits<std::uint32_t>::max();
 
171
    }
187
172
}